Debugging BAD_ACCESS crashes

Newbies can rely on ARC to handle memory management. But personally, i’d rather handling everything myself. Old school!.

Besides that, you’ll probably need to support iOS 4 devices, as well. So… at least for now, Memory Management is kind of a mandatory chapter, to everyone!.

So what happens when you get a ‘BAD_ACCESS’ crash?. There are just so many scenarios that can trigger that crash… but the most common is simply a message sent to a dealloc’ed object.

Objective C runtime comes with a really powerful feature: Zombies!. By setting a flag, ‘release’ objects are, internally, replaced by a ‘placeholder object’.

What’s the meaning of this?. Simple!. ObjC runtime helps you determine if there is any released object that’s getting sent a message. If that’s the case, you’ll get a message in Xcode console.

How do we enable Zombies?. Mmmmmm… in Xcode 4.3.2, you need to do this:

1. Product >> Manage Schemes >> Bottom left corner… ‘Edit’
2. Select ‘Run’ in the left column
3. Select the ‘Arguments’ tab
4. Add an ‘Environment Variable’ called NSZombieEnabled, with ‘YES’ as value.

Important: Remember to remove this setting after you’re done. Otherwise, ‘Leaks’ instrument will be… useless!

 

Using ‘performSelector: withObject: afterDelay:’!

Sometimes, when developing an iOS application, we need to do something like ‘displaying a spinner’, and right after that, do a tedious task, such as query’ing a database, sorting a file, or hitting a backend.

As you may (or may not know)… all of the UIKit framework works on the Main Thread (with several exceptions, set aside). A common problem we might encounter is that… if you begin a long process after initializing an ActivityIndicatorView, the main thread will remain locked out, and thus… the spinner will never begin.

The easiest solution i could come up with looks something like this:

[_spinner startAnimating];
...
[self performSelector:@selector(doSomething:) withObject:someObject afterDelay:0.1f];
...

What’s this??. Simple!. We’re scheduling the ‘doSomething’ selector, in the current runloop, to be executed after 0.1 seconds. That ‘leaves room’ for the mainThread to initialize the spinner (which, internally, will spawn another thread).

That way your app won’t get a nasty freeze … and the spinner will keep on rocking!

Preventing Paste in UITextField

Suppose that your app has a custom keyboard (or component) which populates an UITextField. So… suppose that you need to enable the User Interaction with that control. However, you don’t wanna anyone pasting values right there… because you wanna force the user to rely on your custom keyboard.

UITextField lacks a ‘disablePaste’ property. In order to do this, we’re gonna need to subclass UITextField. Our subclass should look like this…

@interface MyTextField : UITextField
{
BOOL _disablePaste;
    BOOL _disableCut;
    BOOL _disableSelect;
}

@property (nonatomic, assign) BOOL disablePaste;
@property (nonatomic, assign) BOOL disableCut;
@property (nonatomic, assign) BOOL disableSelect;

@end

Nice, ha!?. Let’s see the actual implementation, now!:

@implementation MyTextField

@synthesize disablePaste    = _disablePaste;
@synthesize disableCut      = _disableCut;
@synthesize disableSelect   = _disableSelect;

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    if ( _disablePaste && action == @selector(paste:) )
    {
        return NO;
    }
    else if ( _disableCut && action == @selector(cut:) )
    {
        return NO;
    }
    else if ( _disableSelect && (action == @selector(select:) || action == @selector(selectAll:)) )
    {
        return NO;
    }
    else
    {
        return [super canPerformAction:action withSender:sender];
    }
}

@end

UIView with Rounded Corners

Sooner rather than later, you’ll probably end up with a simple yet tricky requirement: an UIView with rounded corners.

iOS SDK has no ‘radius’ property. Ohhh wait!. Yeah, it actually has!. But the catch to it is that you need to import Quartz framework, first:

#import <QuartzCore/QuartzCore.h>

Also, you need to link the ‘QuartzCore.framework’. Otherwise the import won’t work.

So… how do you actually display an UIView with rounded corners?. Easy!

[_someView.layer setCornerRadius:6];

See?. Just a line of code. Kung fu isn’t about a lot of spaghetti code. It’s about knowing what to do!

Removing Push Notifications from NotificationBar

I have come up with a weird problem…. which goes as follows:

  1. The app receives a Push Notification.
  2. You tap over the PN (in the iOS notification center).
  3. The app gets launched… and you handle the notification
  4. Problem: the notification remains in the ‘notification bar’.

How do you clean it ?. Well… this isn’t in Apple’s docs. But i’ve figured out that if you execute the following line of code, the notification ‘gets acknowledged’:

[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];

Nice, ha?.