Saturday, November 17, 2012

Using the iOS simulator for debugging

If you spend some time with the iOS simulator you'll notice the "Debug" menu, which contains some capabilities that come handy when investigating problems with apps under development.

Such a potential problem could be flickery or jerky animations. Since the duration of the animation on normal use can be pretty short, it may be difficult to see what's going on. Using the "Toggle Slow Animations" option, the first under the "Debug" menu, slows it down enough to allow getting an insight on what may be the problem. For an example of such problem, and the difference that slower animations makes, see the video below:



Once we have visibility on the problem, we can try various fixes and use the slow-mo animations to see if the fix produces a better outcome:


Another group of debugging functionality has the "Color Blended Layers", "Color Copied Images", "Color Misaligned Images" and "Color Offscreen-Rendered" options. All these options can be used to expose inefficient composite drawing, and they're also available through Instruments.

Yet another group of functionality appears under the "Location", which allows simulating changing the location for apps that use location services.

I'm amazed by the quality of development tools that Apple provides, far exceeding other platforms.

If you have an app developed, perhaps by an outsourcing developer like me, and notice some problems with animation, you may ask your developer to toggle those options and produce a screen recording of the app running in the simulator, like I did above, to prove that any issues have been addressed.


Saturday, November 03, 2012

How to access backing ivars for inherited properties in Objective-C

I had a superclass that declared and synthesized a read only property, meant to be set in its subclasses. The code was something like this:


@interface A : NSObject
@property (nonatomic, readonly) NSUInteger prop;
@end

@implementation A
@synthesize prop = _prop;
@end

@interface B : A
@end

@implementation B

- (void)establishValueForProp
{
    _prop = 1// PROBLEM !!!
}

@end


The instance variable backing the property seemed to be invisible in the subclass. The error was pretty unclear when compiling an iOS app: "Use of undeclared identifier '_prop'".  To get around the error I did the following:


@interface A : NSObject {
    NSUInteger _prop;
}
@property (nonatomic, readonly) NSUInteger prop;
@end


That is, I explicitly declared the backing variable in the declaration of the superclass.

Interestingly, when I was preparing this blog post I compiled the code above as a "Command Line Tool" type of project, not an iOS app. The error was different, dare I say better, more telling of the root cause: "Instance variable '_prop' is private". So it's a matter of the visibility of the ivar, so perhaps a better fix would be:


@interface A : NSObject {
    @protected
    NSUInteger _prop;
}
@property (nonatomic, readonly) NSUInteger prop;
@end


Kind of interesting though that properties are synthesized by default as private ivars. Learned something new.