I’m pretty new to iPhone development.
I mean, I’ve only been using Objective-C as a language since January this year. Almost a decade of C++ experience before certainly helped me pick up a few concepts, but I’m certainly not about to go parading myself as a guru anytime soon. In fact, I still end up turning to Google on a daily basis for insight on whatever issue I’m having with Cocoa Touch that hour.
Something I can’t help but make notice of are the number of accepted solutions out there that are bad. Not wrong. Most every time I find a solution it does indeed solve the problem at hand. But not elegantly. Not efficiently. Not well written, not well named, not well tested. And really, just not good code. The examples that spring to mind include C++ code that marked int and float parameters as const in a member function (these integral types are copied when pushed onto the stack for a function call – they’re the same size as a pointer anyway. Marking them const isn’t const-nazi power, it’s just redundant) and some Objective-C code that didn’t bother naming the second parameter of a method (Obj-C has a quirky style of naming any parameters after the first one, leading to highly descriptive method names like
Not using this convention shows a deep misunderstanding of the language).
Any new or learning programmer that finds a solution of this sort and then tries to copy-paste said code into their project will be met with a rather unpleasant surprise. Their code instantly becomes less consistent, less standardised and less maintainable. Let’s be honest though – they deserve it.
Yes, I bet you thought this post would be a rant about how “solutions never work when I copy-paste them into my DetailViewController.m”. Not so, and shame on you sir for thinking so! For you see, I like it that Google’s proferred solutions don’t work like cookie-cutter magic. For me, as I expect it is with most people, if all I do is copy and paste then I don’t learn anything. If the code works without me having to do anything then the next time I get faced with a similar challenge my first thought isn’t going to be “I’ve solved this before”, it’s going to be “where was that website that solved this for me?”. And frankly, those people I’ve seen that do try to copy-paste the code and then comment asking for it to be slightly modified to suit their needs usually deserve whatever issues they bring upon themselves. And maybe it will eventually help them: I know from my years of programming that one of the best motivators for writing good code is having to maintain bad code in another system.
So bring on the bad solutions – seriously. As a blogger I’m usually tempted to try and make the code I release here robust and reusable and free of coupling issues. I don’t plan to stop that – I like to think that keepiing these things in mind are indicative or where I’m at as a programmer, these are the worries I’ve earned and I’m not going to drop them so that someone else can learn from mistakes I shouldn’t have made. But I’m not going to spend extra time to make that code as pretty and useful as possible: it’s up to the person that wants to use it to get in there and change every line and variable name that they need to – and learn what the code actually does at the same time.
Posted by Tatham
| Tagged: Coding
I made the discovery this week that the vector math library I had written for my current project wasn’t right: I needed to transpose any matrix I got from an OpenGL glGet… call before I could use it properly, otherwise my matrix-vector and matrix-matrix operations would just return junk values. A quick Google search revealed a pretty big point of confusion around the OpenGL spec: column-major or row-major matrix representation? Which as it turns out is two points: how you store your matrices and how you represent your vectors.
There are two schools of thought on how to treat vectors when doing matrix-multiplication: traditional math treats them as columns in a 1-dimensional matrix, like in Figure 1.
Computer science, on the other hand, has tended to write them as a row, like in figure 2. I assume the difference comes about because the first method is an absolute bitch to try and type, but I’m only guessing. Anyway, the confusion comes about because the OpenGL spec is written using vectors-as-columns notation, in an attempt to bring us unruly computer scientists in line with the rest of mathematics. The way in which the code for a matrix-vector operation is written will be different depending on whether a vector is treated as a row or as a column.
The second point is how to store a 4 by 4 matrix in a contiguous bit of memory: to map it columns-by-column, like in figure 3; or store each row in order, like in figure 4. Obviously the position of data in memory will also affect how the actual code to perform vector-matrix operations is written.
So, as it turns out there was an issue with backwards compatibility when writing the OpenGL spec: they wanted to use vectors-as-columns, but to do so would break compatibility with the previous GL, which treated vectors as rows. So they did a sneaky on us. They wrote into the spec that OpenGL was column-major. The thing with column-major and row-major matrices is that you can switch between them by transposing i.e. a column-major translation matrix can become the same matrix in a row-major system by flipping its values along the diagonal like in figure 5.
And the thing with treating vectors as columns, is that you can switch between them by transposing i.e. in a vectors-as-rows system, you could treat vectors as columns by using the transpose of the matrix you’re multiplying against. See figure 6 (at which time I realised that Open Office comes with a perfectly good math editor).
So by taking the existing vectors-as-rows system, with row-major storage, and making it a vectors-as-columns system with column-major storage, OpenGL leaves us with the transpose of the transpose: the exact same matrix we started with!
Moral of the story: if implementing a vectors-as-rows math library is your thing – as it is mine for previously metnioned typing issues – and storing matrices row-first comes natural: keep doing both! If vectors-as-columns is your secret perversion, make sure you implement it with a healthy dose of column-major matrix storage or people will look at you weird. But no matter what you do, don’t waste almost a week writing and rewriting your matrix code to try to get it to play nice with OpenGL – read this article again instead
Posted by Tatham
I read a very interesting article this week. For those put off by the wall of text that the link is, I’ll summarize it thus: the author analyses all the available data on App Store sales to calculate average sold App prices ($3.95), the average spending on apps per device sold (around $14 a year), free app downloads per device (about 80) and the average income of an iPhone App Developer (about $3000 a year). That’s pretty bleak.
But the analysis doesn’t end there. No, the App Store resides in a place described in one of my favourite books as Extremistan: where the way we think of averages doesn’t apply like we expect. The success of the few (like Angry Birds, with over 4 million downloads) skews the average, while the vast majority of apps exist in the long tail of the bell curve, earning bitter nothingness. After crunching the numbers: only HALF of all developers will make more than about $600. And I thought the average was pretty bleak.
Things are far from hopeless – in Extremistan the top few take the lion’s share of a near limitless success, but the smart are never truly dead. It’s always possible to carve out a living by targeting the right niche, and I’m almost certain this is exactly what drives Flower Garden and similar games.
Finally, the post concludes with a reminder of just how few people own an iPhone. 3%. It’s a small number. iPhone doesn’t even make the top 10 smartphones list. In fact the author goes so far to suggest that the savvy developer should target iPhone last of all the mobile platforms.
But its here that I disagree with the original article. Sure, 97% of people don’t own an iPhone – but only a very small percentage of those people would buy apps or even have access to them through their phones or networks. The iPhone, and by association its rival platform Android, is an environment where people expect to buy apps. An average of $14 spent per handset – how likely is it that there are people spending thousands upon millions of dollars skewing that figure? Not very. And as most of those apps bought tend to be games, games developers have a slightly better chance of finding a niche and making money than any other app developers. Luckily, that’s what I’m working on right now…
Posted by Tatham