Calvin's

Icon

designs and hacks. people and products.

A Review of Rob Napier, Mugunth Kumar’s iOS 6 book; and advanced debugging with Python + LLDB

I have had the benefit of a sneak preview into Rob and Mugunth’s upcoming book release - iOS 6 Programming Pushing the Limits: Advanced Application Development for Apple iPhone, iPad, and iPad Touch- which is an updated release to their successful iOS 5 pushing the limits series.

As any veteran programmers would know, one of the most important skills (among a multitude of skill requirements) to master is the art of debugging an application.  Chapter 19 provides an excellent coverage of this topic in the context of iOS apps.  Beginning with a conceptual introduction to LLDB (Apple’s Lower Level Debugger) and the difference from the older version of the debugger – GDB – the chapter introduces the intermediate programmer to the actual mechanics of debugging with LLDB and the use of breakpoints (which is no different from the use of breakpoints from many other advanced editors or debugging tools).

Breakpoints

Having mucked around with almost 5 conceptually simple iOS apps, I am no strange to using breakpoints to zero in on problems.  What is interesting, however, is the detailed explanation of different types of breakpoints – exception breakpoints, symbolic breakpoints.  Of particular interest and of learning value to me personally, is the use of Ctrl-Click + “share” on the breakpoint to write a breakpoint state into a `xcshareddata` directory, which can be saved into git and so shared with a fellow developer.

Watchpoints

Watchpoints are also interesting to me, being useful for specifically tracking data mutation events – particularly for global variables that have changed, in the context of Singleton implementations, Core Data persistent store coordinators or API engines.

Advanced Use of Debugger through Python Scripting

For our normal, simple use cases, introspecting objects at breakpoints is a simple matter of typing

po myObject
po myDictionary
po myArray

For scalar variables (e.g. integers or structs), we will of course use

p (int) self.myAge
p (CGPoint) self.view.center

What if we need to search through a very large array containing a large number of objects?  This is where we might have problems manually reading the 10,000 objects that are printed out.  In such a case, we can actually use Python to run a search.  Jumpt into the python shell prompt from the lldb prompt by typing “script”. Then, via the great example from the book:-

>>> import mypython_script
>>> array  = lldb.frame.FindVariable("myArray")
>>> yes_or_no = mypython_script.search_object(array, "<search element>")    # search_object is a method we write in our custom mypython_script .py file.
>>> print yes_or_no

This nice little trick from the book goes straight into my personal bookmark.

Finishing Up

The chapter ties up neatly with an explanation of how NSZombieEnabled flag/environment variable is used to track objects in memory, a summary of various types of Application crashes one commonly encounters and how crash stacks can be collected – “natively” via iTunes as well as on 3rd party services like TestFlight and HockeyApp.

All-in-all, this is a must-have book for any professional iOS developer and certainly a level-up for me.  I have merely covered specifically this one chapter of a very detailed and extensive pro manual and I am certainly looking forward to grabbing a copy (or receiving a copy free ;-)) from Mugunth.  Grab it at Amazon.com if you think this is something that would help you build even more awesome iOS apps - iOS 6 Programming Pushing the Limits: Advanced Application Development for Apple iPhone, iPad, and iPad Touch.

Property attributes in Objective-C

In property declarations in Objective-C, we need to be specific about the attributes of that property.

For instance:-

@property(nonatomic, retain) UITextField *userName;

@property(atomic, retain) UITextField *userName;

@property(retain) UITextField *userName;

nonatomic vs atomic

“atomic” is the default if it is not specified. We always use “nonatomic”. You can use this attribute to specify that accessor methods are not atomic. (There is no keyword to denote atomic.) Properties are atomic by default so that synthesized accessors provide robust access to properties in a multithreaded environment—that is, the value returned from the getter or set via the setter is always fully retrieved or set regardless of what other threads are executing concurrently.

retain vs. copy vs. assign

  • “assign” is the default. In the setter that is created by @synthesize, the value will simply be assigned to the attribute. My understanding is that “assign” should be used for non-pointer attributes.
  • “retain” is needed when the attribute is a pointer to an object. The setter generated by @synthesize will retain (aka add a retain count) the object. You will need to release the object when you are finished with it.
  • “copy” is needed when the object is mutable. Use this if you need the value of the object as it is at this moment, and you don’t want that value to reflect any changes made by other owners of the object. You will need to release the object when you are finished with it because you are retaining the copy.

Is that all? Nope… apparently, we can also specify our property’s access rights.

readwrite vs readonly

“readwrite” is the default. When you @synthesize, both a getter and a setter will be created for you. If you use “readonly”, no setter will be created. Use it for a value you don’t want to ever change after the instantiation of the object.  So if for any reason, you need a property to be readonly, it will look something like this:-

@property(nonatomic, retain) UITextField *userName;

Simplest explanation of memory allocation

Many years ago, when I was just starting to pick up the art of programming, I asked some of my much more experienced peers to explain to me – like I am five years old – the concept of memory allocation.  Unfortunately, this topic was usually explained in such a convoluted, complicated way that it served to confuse me more than actually illuminate.

As I have been brushing up on my Objective-C skills for a couple of apps I am making, I revisited the topic of memory allocation again.

And in the gem of a tutorial written by Matthijs Hollemans, I found these two diagrams:-

 

Completely self-explanatory! I like. :-)