Sunday, 30 October 2011

The Death of Global Variables

From: http://www.cocoanetics.com/2009/05/the-death-of-global-variables/


The topic of global variables is a highly philosophical and emotional one as I should later see. Programming teachers usually try to dissuade their students from using them wherever possible, but newcomers still insist on using them. And then there is the rebel amongst seasoned programmers who rides to the rescue of global variables. “No! Globals are not evil! It’s evil people that abuse them and kill programs with them.”
My usual approach is quickly steer the topic to something completely different. Did I mention that I am getting married in just 1 week?

Real Global Variables

Ok, but seriously, yes, you can create global variables if you absolutely insist. You can do this in C like this:
int myGlobalVar; // local declaration
And in all other classes/modules that you want to be able to access it you go:
extern int myGlobalVar; // externally linked
This external declaration you could pack into a header and #import this header everywhere you want to access this global variable. Only the declaration really reserves the memory for the variable. The “extern” keyword tells the linker (which runs after the compiler) to resolve all external references to point to the real declaration.
Ok, now, my son, I have shown you the pack of cigarettes. Will you please promise me not to smoke them in secret?
I generally call global variables evil because they tempt you with ease of use and seduce you away from encapsulated and easy to maintain code. The main reason being that only you – the original programmer – know what all those variables mean and where the declaration is buried.
Generally you don’t want to be dependent on such knowledge, you want clear cut pieces where you group together stuff that belongs together logically and bundle in the functions to work on this data. This concept is called “encapsulation” and is core to the principle of OOP (Object Oriented Programming)

“All in” Application Delegate

When I started out with trying to adhere to the Model-View-Controller paradigm I though this means that you put all data operations into the app delegate. Getting to the app delegate is simple enough, you only need to do it like this:
MyAppDelegateClass *appDelegate = [[UIApplication sharedApplication] delegate];
 
[appDelegate someMethod:..];
Again, very tempting. You feel much smarter because you don’t need global variables, but then you find yourself constantly copy-pasting the first line of the example because from everywhere you are needing to call methods and access data that you put in the app delegate. My first released apps are still full of these until I can find time to go back in and fix that.

Shared Instances

The cleanest, most professional method I have found on my travels is to use so-called shared instances. You basically create a class method that instantiates a single instance of the class (aka a “singleton”) on the first call and returns this instance on subsequent calls.
Here is an example showing an Engine class you might find in a board game. Note that you still can use c-style arrays if you so choose, but it’s all nicely packaged into a class.
Engine.h
#import 
@interface Engine : NSObject {
 NSUInteger board[100];  // c-style array
}
 
+ (Engine *) sharedInstance;
 
- (NSUInteger) getFieldValueAtPos:(NSUInteger)x;
- (void) setFieldValueAtPos:(NSUInteger)x ToValue:(NSUInteger)newVal;
 
@end
Engine.m
#import "Engine.h"
 
@implementation Engine
 
static Engine *_sharedInstance;
 
- (id) init
{
 if (self = [super init])
 {
  // custom initialization
  memset(board, 0, sizeof(board));
 }
 return self;
}
 
+ (Engine *) sharedInstance
{
 if (!_sharedInstance)
 {
  _sharedInstance = [[Engine alloc] init];
 }
 
 return _sharedInstance;
}
 
- (NSUInteger) getFieldValueAtPos:(NSUInteger)x
{
 return board[x];
}
 
- (void) setFieldValueAtPos:(NSUInteger)x ToValue:(NSUInteger)newVal
{
 board[x] = newVal;
}
 
@end
To test this new class we simple put the #import into our app delegate and a couple of lines:
// at the top: #import "Engine.h"
 
Engine *myEngine = [Engine sharedInstance];
 
[myEngine setFieldValueAtPos:3 ToValue:1];
 
NSLog(@"pos 3: %d",[myEngine getFieldValueAtPos:3]);
NSLog(@"pos 2: %d",[myEngine getFieldValueAtPos:2]);
You can see that you don’t need to alloc-init the class, just always retrieve the sharedInstance pointer. Behind the scenes this class method will create the instance on the first call and save it in a static variable. Static variables retain their value indefinitely.
I am told that you don’t need to worry about the release because all of the app’s memory will be cleaned up when it quits anyway. But if you want to be extra-nice you can put a release for the sharedInstance into the dealloc of your appDelegate. Though I found that the appDelegate’s dealloc never actually gets called anyway. I suspect that is because the iPhone OS considers it quicker to just kill the app and free up all of it’s memory in one go.
You can also pack all other engine-related methods and data variables into this Engine class. Just not anything that has to do with displaying it. This makes the engine reusable. You might create variants of your app with totally different display paradigms but because the Engine class stands by itself you can reuse it.
In summary I am recommending that you don’t use any technique that will cause you more work in the future. You can mix and match techniques as you choose once you are a “grown up developer” and understand what you are doing.
Until you do, please refrain from using global variables and putting it all into the poor app delegate, but instead make shared instances your method of choice for globally accessible data.

Tuesday, 11 October 2011

NSKeyedArchiver Tutorial

Sometimes we may want our app to save some data before it terminates and load the data after it is opened again. There are usually two ways to achieve that:

1. using NSUserDefaults.
2. using NSKeyedArchiver.

Both are very standard methods provided by Cocoa, but as NSUserDefaults is designed for storing default settings rather than data inside the app, in most of the cases, you want to use NSKeyedArchiver instead.

To use NSKeyedArchiver, first of all you need to add a protocol called NSCoding to the class whose properties are supposed to be saved and then loaded in the app.

For example, you have a class called Student which is used to store some information about a student. Its header may look like this:
@interface Student : NSObject <NSCoding> {
    NSString *studentID;
    NSString *studentName;
}

@property (copy) NSString *studentID;
@property (copy) NSString *studentName;

+ (Student *)initWithStudentID:(NSString *)ID andStudentName:(NSString *)name;

@end
You also need to implement two delegate methods initWithCoder: and encodeWithCoder: in the .m file of this class. It may look like this:
+ (Student *)initWithStudentID:(NSString *)ID andStudentName:(NSString *)name {
    
    Student *student = [[Student alloc] init];
    
    student.studentID = [NSString stringWithString:ID];
    student.studentName = [NSString stringWithString:name];
    
    return [student autorelease];
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super init]) {
        [self setStudentID:[aDecoder decodeObjectForKey:@"studentID]];
        [self setStudentName:[aDecoder decodeObjectForKey:@"studentName"]];
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:studentID forKey:@"studentID"];
    [aCoder encodeObject:studentName forKey:@"studentName"];
}
Note that you must use the same key for one object in method initWithCode: and encodeWithCoder:, or the app will not be able to find the saved object when decoding. The key is the only identifier of its corresponding object. The encoded data will be stored in a binary formatted file on your disk.

Now we are on the halfway. What we need to do then is to tell the app that we want to save some data before it is terminated. Find the applicationWillTerminate: method in YourProjectAppDelegate.m file, and add the following code:
- (void)applicationWillTerminate:(NSNotification *)notification {
    
    [self saveDataToDisk];
}
The code will call the method saveDataToDisk when user closes the app. So we're gonna implement that method to tell the app the we want to save some data. The code may look like this:
- (void)saveDataToDisk {
    NSString *path = @"~/Documents/data";
    path = [path stringByExpandingTildeInPath];
    
    NSMutableDictionary *rootObject;
    rootObject = [NSMutableDictionary dictionary];

    [rootObject setValue:student forKey:@"student"];
    
    [NSKeyedArchiver archiveRootObject:rootObject toFile:path];
}

The object student is an instance of Class Student. In this example, we save it in a file named data under the the Documents folder.

Alright, now we should be able to save our data into the disk. Now the only thing left is to load the data. The method may look like this:
- (void)loadDataFromDisk {
    NSString *path = @"~/Documents/data";
    path = [path stringByExpandingTildeInPath];
    
    NSMutableDictionary *rootObject;
    rootObject = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

    if ([rootObject valueForKey:@"student"]) {
        student = [rootObject valueForKey:@"student"];
    }
}
The method does two things: 1. Tell the app where the saved file can be found; 2. Assign object with the corresponding key to the student instance.

You can call this method whenever you believe is necessary to load the data from local disk to your app.

Happy Coding :)

Monday, 10 October 2011

Using Blocks in Objective-C

From: http://pragmaticstudio.com/blog/2010/7/28/ios4-blocks-1


iOS 4 introduces one new feature that will fundamentally change the way you program in general: blocks. Blocks are an extension to the C language and thus fully supported in Objective-C. If you’re coming from a programming language such as Ruby, Python, or Lisp, then you know the power of blocks. Simply put, blocks let you encapsulate chunks of code and pass them around like any other object. It’s a different style of programming that you’ll want to become familiar with to take advantage of new APIs in iOS 4.

Let’s start by taking a look at two examples of where you might use blocks in iOS 4: view animations and enumeration.

Blocks By Example

As our first example, suppose we’re creating a card game and we want to animate sliding a card from the dealer’s hand to a player’s position. Fortunately, the UIKit framework does all the heavy lifting when it comes to performing animations. What gets animated, however, is specific to your application. You specify what will be animated in a block, and toss it over to theanimateWithDuration:animations: method, like so:
[UIView animateWithDuration:2.0
    animations:^ {
        self.cardView.alpha = 1.0;
        self.cardView.frame = CGRectMake(176.0, 258.0, 72.0, 96.0);
        self.cardView.transform = CGAffineTransformMakeRotation(M_PI);
    }
];
When this animation block is run, our card view will animate in three ways: change its alpha to fade in the card, change its position to the lower-right of the frame (the player’s position), and rotate itself 180 degrees (to give the dealer style points).

Our second example of blocks is to enumerate over a collection of cards and print the name and index of each card. You could use a for loop for this, but in iOS 4 the NSArray class has a handy enumerateObjectsUsingBlock: method that takes a block. Here’s how to use it:
NSArray *cards = [NSArray arrayWithObjects:@"Jack", @"Queen", @"King", @"Ace", nil];
[cards enumerateObjectsUsingBlock:^(id object, NSUInteger index, BOOL *stop) {
    NSLog(@"%@ card at index %d", object, index);
}];
As we’ll explore a bit more later, this block takes three parameters: the current element in the array, its index, and a flag to signal whether enumeration should stop (which we’ve ignored). The enumerateObjectsUsingBlock: method calls the block once for each element in the array and supplies the parameters.

So the upshot of using blocks in your Mac and iOS apps is that they allow you to attach arbitrary code to Apple-provided methods. Although similar in concept to delegation, passing short inline blocks of code to methods is often more convenient and elegant.

That’s a good start, but it’s important to understand what’s going on. Whenever I’m learning anything new, I like to break it down into its simplest elements, get comfortable with how they work, and then (hopefully) put everything back together again. That way I feel confident with the code I write and can quickly debug any problems. So let’s step back for a minute and learn how to declare and call basic blocks.

Block Basics

A block is simply a chunk of executable code. For example, here’s a block that prints the current date and time:
^ {
    NSDate *date = [NSDate date];
    NSLog(@"The date and time is %@", date);
};
The caret (^) introduces a block literal and the curly braces enclose statements that make up the body of the block. You can think of a block as being similar to an anonymous function.

So if it’s anonymous, how exactly do we use this block? The most common way to use a block is to pass it to a method that in turn calls the block. We saw how to do that earlier with animations and enumeration. The other way to use a block is to assign it to a block variable and call the block directly. Here’s how to assign our block to a block variable called now:
void (^now)(void) = ^ {
    NSDate *date = [NSDate date];
    NSLog(@"The date and time is %@", date);
};
Here’s where things get funky. The syntax for declaring a block variable takes some getting used to. If you’ve used function pointers, block variables will look familiar. On the right-hand side of the assignment we have our block literal (nothing new there). On the left-hand side of the assignment we’ve declared a block variable called now.

Block Syntax

The name of the block variable is always preceded by a ^ and in parentheses. Block variables have an associated type. In this case, the nowvariable can reference any block that returns no value (the first void) and takes no parameters (the void in parentheses). Our block conforms to this type, so we can safely assign it to the now variable.

Once we have a block variable in scope, calling the block is just like calling a function. Here’s how we call our block:
now();
You could declare the block variable in a C function or Objective-C method, for example, and then call it in the same scope. When the block executes, it prints the current date and time. So far, so good.

Blocks Are Closures

If that’s all there was to blocks, they’d be just like functions. But it turns out that blocks are more than just chunks of executable code. Blocks also capture their surrounding state. That is, blocks are closures: they close around variables that are in scope at the time the block is declared. To illustrate, let’s change the previous example around a bit by moving the initialization of the date outside the block:
NSDate *date = [NSDate date];
void (^now)(void) = ^ {
    NSLog(@"The date and time is %@", date);
};
now();
When you call this block the first time, it behaves exactly like the previous version: it prints the current date and time. But there’s a significant difference here. It becomes evident when we change the date and then call the block again:
sleep(5);
date = [NSDate date];
  
now();
Even though we’ve changed the date variable referenced by the block, when the block is called it still prints the original date and time. It’s as if time stood still when the block was declared. And that’s effectively what happens. As execution passes over the point where the block is declared, the block takes a (read-only) snapshot of all the variables in scope that the block uses. You can think of the value of the datevariable as being frozen inside the block. Therefore, whenever the block is called—immediately, 5 seconds later, or just before the app quits—it always prints the original date and time.

Now, the fact that blocks are closures is not particularly interesting in this example. After all, you could have just passed the date as a parameter to the block (more on that next). But closures become really useful when you start passing blocks around to methods because the captured state goes along for the ride.

Block Parameters

Just like functions, blocks can take parameters and return values. Say, for example, we want a block that takes a given number and returns the result of tripling that number. Here’s the block literal:
^(int number) {
    return number * 3;
};
Assigning this block to a block variable called triple looks like this:
int (^triple)(int) = ^(int number) {
    return number * 3;
};
Again, the tricky part is getting comfortable with the block variable syntax on the left-hand side of the assignment. Let’s break it down from left to right.

Block Syntax

The first int is the return type. Then in parentheses comes the caret introducing the block variable called triple. Finally we have a list of parameter types in parentheses (one int in this case). The block literal on the right-hand side of the assignment conforms to this type. Note, however, that as a matter of convenience there’s no need to declare the return type of the block literal. The compiler can infer it from the return statement.

To call the block, you need to pass the number to be tripled and (ideally) do something with the return value, like so:
int result = triple(2);
By way of comparison, here’s how you would declare and create a block that takes two int parameters, multiplies them together, and returns the result as an int value:
int (^multiply)(int, int) = ^(int x, int y) {
    return x * y;
};
And here’s how you’d call this block:
int result = multiply(2, 3);
Declaring block variables gave us an opportunity to explore block types and how to call blocks. The block variable looks like a function pointer and calling the block is similar to calling a function. But unlike function pointers, blocks are actually Objective-C objects. And that means we can pass them around like other objects.

Methods Can Take Blocks

Now, in practice blocks are most useful when you pass them as parameters to methods that in turn call the block. And when you’re passing a block to a method, it’s usually more convenient to use inline blocks rather than assigning the block to a typed variable and then passing it to the method. For instance, we used inline blocks in the animation and enumeration examples we saw earlier.

Apple has added methods to their frameworks that take blocks, and you can write APIs that take blocks, too. For example, suppose we want to create a Worker class method that takes a block and repeatedly calls it a given number of times, passing in the repeat count each time. Here’s how we might call that method with an inline block that triples each number (1 through 10):
[Worker repeat:10 withBlock:^(int number) {
    return number * 3;
}];
The method could handle any block that takes a single int parameter and returns an int result. Want to double all the numbers? Just give the method a different block.

Your Turn

OK, so how would you implement the repeat:withBlock: method above to accept and call a passed block? Give it some thought, and we’ll tackle it in the next installment. In the meantime, practice using blocks by calling the enumerateKeysAndObjectsUsingBlock: method with a block that prints the keys and values of this NSDictionary:
NSDictionary *cards =
    [NSDictionary dictionaryWithObjectsAndKeys:@"Queen"@"card",
                                               @"Hearts", @"suit",
                                               @"10",     @"value", nil];
Have fun.