Mobile App Development

Objective-C Bag of Goods

December 7, 2012

  • Felipe Laso Marsetti
  • 1

Objective-C Bag of Goods

Hello and welcome once more to a Lextech iOS tutorial. Today we are going to discuss some simple tricks, tips and useful time savers when writing your Objective-C code.

A lot has changed since the days of the iPhone SDK and the old Objective-C. Many cool, perhaps unnoticed, features have been added to the language to make things easier for you.

Here’s a brief list of some of the topics we’ll cover today:

  • Private outlets and actions
  • Automatic synthesize for properties
  • Class extension enhancements
  • Subscripting
  • Literal number, array and dictionary declarations
  • No private method declarations required

Private IBOutlets and IBActions

One of the coolest features of modern Objective-C is that you can put your IBOutlets and IBActions inside the implementation (.m) file. This is great news since you’re no longer forced to make all of your actions and outlets part of your public interface.

Here’s a sample class implementation that showcases this functionality:

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UIButton *myButton;

@property (weak, nonatomic) IBOutlet UIScrollView *myScrollView;

@end

@implementation ViewController

- (IBAction)myButtonTapped

{

[self somePrivateMethod];

}

- (IBAction)myUnwindSegue:(UIStoryboardSegue *)segue

{

}

- (void)somePrivateMethod

{

NSLog(@"Called the private method");

}

@end

You’re now able to put your IBOutlets in the class extension and your actions directly in the implementation portion of your controllers.

Another cool feature of modern Objective-C is that you are no longer required to declare your private methods before implementing them. The sample code declares a private method called somePrivateMethod that is then called inside one of the IBActions.

None of the three methods are previously declared and can be called anywhere in your code.

Automatic synthesize for properties

You’re probably all familiar with the whole property declaration/synthesize routine. Many times the synthesize statement was boilerplate code that took up more time and space in your source files than anything else.

Now, you’re allowed to do the following:

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UIButton *myButton;

@property (weak, nonatomic) IBOutlet UIScrollView *myScrollView;

@end

@implementation ViewController

// NO SYNTHESIZE, YAY!!!

@end

Your properties don’t have to be in the class extension un order for this to work, they can be in the header file as well.

If you don’t explicitly synthesize your variables they will have the traditional iVar declaration style that Objective-C developers have used as a standard, that is with the following convention:

Property ->  propertyName

Instance Variable ->  _propertyName

If you recall, that’s similar to having done this in the past:

@synthesize myButton = _myButton;

Despite feeling like a small, irrelevant change, when you have over a dozen properties in your files then the amount of time saved will be quite noticeable.

You can, of course, still synthesize your properties if you desire to use a different naming convention for your iVars. You also need to synthesize them manually when you declare read-only properties.

Class extension enhancements

Another great, great set of features of modern Objective-C is being able to adhere to protocols inside the class extension and declare instance variables in implementation files.

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>

@property (weak, nonatomic) IBOutlet UIButton *myButton;

@property (weak, nonatomic) IBOutlet UIScrollView *myScrollView;

@end

@implementation ViewController

{

NSString *controllerTitle;

}

- (void)viewDidLoad

{

[super viewDidLoad];

controllerTitle = @"My Controller";

}

@end

To put instance variables in the implementation file, simply add an open and closing bracket as shown above and put all your variables inside.

Also look at how this class now adheres to the table view’s data source and delegate protocols in the class extension as opposed to the interface in the header file.

At this rate your header files should probably look as slim as a stick figure

Subscripting and literals

This is probably the coolest addition to the language. Gone are the days of doing stuff like this:

NSArray *myArray = [NSArray arrayWithObjects:@"One", @"Two", @"Three", @"Four", nil];

NSDictionary *myDictionary = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"One", @"Two", @"Three", nil] forKeys:[NSArray arrayWithObjects:@"Key1", @"Key2", @"Key3", nil]];

NSNumber *myNumber = [NSNumber numberWithFloat:1.5f];

Now you can do the following:

NSArray *myArray = @[@"One", @"Two", @"Three", @"Four"];

NSDictionary *myDictionary = @{ @"Key1" : @"One", @"Key2" : @"Two", @"Key3" : @"Three" };

NSNumber *myNumber = @1.5f;

Isn’t this a huge time saver? I mean it’s very clear what’s going on and is similar to JSON or Ruby declarations for arrays and dictionaries. This alone will save you tons of time and lines of code.

It will also make debugging easier because you can read things clearly and writing less code means less bugs you may introduce.

Finally, you can use subscripting to access the values inside dictionaries and arrays. This is how the syntax looks:

NSLog(@"%@", myArray[0]); // Returns "One"

NSLog(@"%@", myDictionary[@"Key3"]); // Returns "Three"

Compare that to the old selectors you had to call in order to get access these elements and the advantages are, once again, clearly evident!

As a small tip, you can also add subscripting to your own classes for retrieving values if you implement the following methods for arrays and dictionaries respectively:

  • (id)objectAtIndexedSubscript:(NSUInteger)index;
  • (id)objectForKeyedSubscript:(id)key;

Additionally if you want to set the values of arrays and dictionaries using subscripting then implement the following methods in your classes:

  • (void)setObject:(id)object atIndexedSubscript:(NSUInteger)index;
  • (void)setObject:(id)object forKeyedSubscript:(id )key;

Wrap up

I these tips help you when writing your iOS or OS X applications. You will certainly save time, have cleaner, better structured files and write fewer lines of codes.

There are other optimizations and features added to the language so be sure to read up on the improvements to LLVM and Objective-C in Apple documentation.