Posted on 2010-05-20 08:00:00
Tags: Apple, iPhone, Objective-C, Rant, Coding
As stated before, I am pretty new to Objective-C programming. Normal C? Not a problem at all! But this object memory management process in Objective-C still gives me a hard time.
The first attempt was simple: I added a lot of NSLog() messages in my dealloc() methods and see which ones I expected to see were not showing up. That were for example all my inherited UIViewControllers... They were not released after they were closed. It is a hard way to do it like this, but it gives you a feel of what you are are really doing wrong.
Then I had a look at the "Leaks" analyze tool in Objective-C (Run -> Analyze -> Leaks) and ran my program. At the end, after a couple of refreshes, it consumed 5 Mb of memory. 5 Mb, is that such a deal? Yes, it is when all the program does is retrieve an XML feed and extracts some data. Oh, and every time it refreshed it lost another huge chunk of memory. Yes, that is a big deal. Luckely the "Leaks" analyze tool tells me which kind of objects it is leaking and when, so you might be able to plug them if you go methodically through the features of your program.... Checking the retainCounters is the way to go.
The next step was to implement a button which terminates the program. Apple doesn't permit you to have apps in their AppStore which have this feature, their usability design is: "If you want to terminate a program, you press the big round Home button at the bottom of the screen.". This breeds lazy programmers, there is no way to properly deallocate all the objects you have. And the excuse you read on the forums about it is "When you terminate your program, the operating system will take care of that.". Absolutely correct, but with some-form-of-multitasking around the corner the current system of "Short living apps won't be able to hog a lot of memory" is over. Plus that it will not show the lazy programmer that he has a serious problem in his code!
And the last tool I thought about was something like a static analysis tool, like Clang (I didn't know this at that moment, and have not used it yet, but it is included in XCode these days). I found a front-end for it called the Analysis Tool at http://www.karppinen.fi/analysistool/ and ran my code through it. Four hundred warnings, and most of them related to objects not being freed.
What I learned from this was: Always "autorelease" the local objects. Assignments increase the retainCounter. Check the retainCounters of the objects you release in your dealloc() methods. Don't trust yourself. And wait for the day that you will be able to see at termination of your program what you have leaked.
To be continued.
Posted on 2010-05-04 08:00:00
Tags: iPhone, Apple, Objective-C, Coding, L-Space
And so do 50 million other people on this planet. So far nothing exciting :-)
The first impression is good (just as everybody else says): Works intinutive, apps are great. Addiction factor: High. Very high unfortunately.
As a hardcore tinkerer, of course I'm interested in how to make apps for it. And so the drama began: You need an iMac, and one one with an Intel chip in it (the one we have here has a PowerPC), so I needed to buy a Mac mini. And then I needed to buy a digital certificate from Apple so I could store the programs on the physical iPhone instead of on the iPhone Simulator (great piece of software BTW!). And then I needed a book, so I got Erica Saduns 'The iPhone Cookbook' (after taste-testing a downloaded copy). And then I had to learn Objective-C...
Objective-C, according to Wikipedia, is "a reflective, object-oriented programming language which adds Smalltalk-style messaging to the C programming language.". Although never used C++, I can handle object-oriented programming from my history with TurboPascal in a previous life and PHP and Perl from more recent lives. Smalltalk messaging is, as far as I use it but in reality much more, a way to call functions in other objects.
Compared with C++, I like the style of the Smalltalk message passing to call an other object's function: It makes the difference between the properties of an object (foo.bar) and the functions ([foo bar]) clearer. Also the nested way of messaging makes the code simpler ([[[[ClassFoo alloc] init] randomfunction] release]).
The way functions in objects in Objective-C are defined and called is a large improvement over C++ (unless I've totally missed this feature in C++): A function definition is like (void)displayString:(char *)text withStyle:(int)style centered:(bool)centeredText and function calls to it are like [displayString:"Foo" withStyle:UNDERLINED centered:FALSE]. That makes it easy to make sure you a. have all the parameters in the right order and b. you can have multiple functions with the same order of types (char *, int, bool) but with different names for the arguments.
Good, now the things which don't work out so well yet... Memory management! It is a drama in every language, although I had it pretty much under control in OO-Pascal and C, here it goes a little bit further with garbage collection. I don't mind garbage collection for the things that Apple provides inside the iPhone SDK, but I like to keep track, and the clean-up afterwards, of my own garbage: The following initializes a string and automatically releases it when nobody is using it anymore: NSString *s = [[[NSString alloc] initWithString:"Foo"] autorelease]. Every object, in this case the NSString object, has a counter which keeps track of the amount of references to it. Once the counter is zero, the object gets cleaned up. So the option "autorelease" used earlier, that feature should automatically release, unless there are other references to it, the NSString object when the function has ended (at least that is how I see it). But does this magic really happen? There is no way to check it, we just have to believe the system wrks. For the simple NSString object here it is not so much of an issue, except when I believe it should be still there and it has been released. In pure C you would get a segfault if you do something on invalid or NULL pointers, but in this messaging system you can easily send messages to nil objects without things falling apart. So the protection I had as a C programmer during the development (when you run the program and something doesn't initialize properly, it aborts the moment you try to do something with that piece of data) is now gone because the place it goes wrong might only show up in the output to the user instead of as an interruption of the program.
So, how am I going so far? With regarding to the GUI objects that the iPhone provides (views, input fields, scrolling), I have most of it under control. The rest is learned when required: Thanks to the power of the Google search engine and the various iPhone development communities, all the questions I come up with are already asked and answered.
Right now I have released one app called L-Space. I use it to keep track of collection of Discworld books, to find out which ones I already own and which ones I haven't read yet. You can find it in the iTunes store or in the iPhone Apps program. A bigger version will allow more book-series and maybe the option to edit them.
The next one I'm working on is an aggregator (more an advocacy thingie) for information about the FreeBSD Project: It shows the YouTube videos, the Planet FreeBSD feed, the News Flash and the location of FreeBSD Commiters in the map.
Oh, and about the addiction: I manage to keep it quite well under control, except for the Words with Friends (a non-realtime version of scrabble) and Bridges (Also known as Hashiwokakero), with which I waste hours and hours on in the train.