Cocoa Samurai

Thursday, March 07, 2013

Basic MVVM with ReactiveCocoa

Update: This article has been updated to reflect the changes in the latest stable ReactiveCocoa v2

MVC - One Pattern to Rule them all

The MVC design pattern has existed since the late 1970s and has been in use in the Foundation, AppKit & UIKit Frameworks for a long time now. At its heart is a very simple design and a good idea. The Design is this

As you can see we have 3 components

  • Model - The Data model our view is managing
  • View - The User Interface on screen consisting of things such as text fields, buttons, etc.
  • Controller - The Controller in MVC exists to decouple the view from the model.

In the MVC design pattern, the controller separates the model from the view so that each can change independently. If we didn't have such a decoupling then every time the model changed, the view would need to change as well. In this design pattern interactions happen like this

  1. A view triggers an action to happen on the Controller
  2. The Controller executes said action and updates the model
  3. The controller may receive a notification from the model that it was updated.
  4. The Controller updates the view

This is the MVC waltz that we do when working with this design pattern, overall it works fairly well. The reason we use this is because this pattern decouples the view from the data model, letting the controller be an intermediary between the 2. This allows the controller to access the parts of the data model that need to be accessed and allows for the controller to do things like properly format the data for the view.

MVVM - For a Better World

MVVM stands for Model-View-ViewModel, and comes from Microsoft and is based off of the MVC design pattern. To be more precise, it is based off of Martin Fowlers Presentation Model. To some people at first it looks very similar to the MVC design pattern and people become confused as to how its different. So let me show you the pattern and then we'll see how its different

In this pattern we still have 3 components, the same as MVC however there are differences. In MVVM I and others tend to group the View Controller in with the View so that those 2 things are treated as 1 component. The most important part is that we've introduced the View Model and that the view gets updates pushed at it from the view model through some sort of observer. In this article ReactiveCocoa will be that observer.

In the MVVM pattern the View Model encapsulates data/properties that the view can bind to and any validation logic and actions that can be performed. For Instance if you had a button that needs to change its title text you would have a property on the view model that the button can bind its title property to. The same goes if you need to change the color of a control or enable and disable the control. In this pattern we are essentially taking the state of our app and putting it into a view model. Its also good to note that as far as the View Model is concerned it doesn't care where it gets this state from. It doesn't matter if it gets it from its init method, a file on disk, Core Data, a database, etc.

Because we are encapsulating the state of our view in such a way this has several benefits.

We don't need to test the UI

In terms of standard controls we don't need to test our UI's at all since the controls are just binding their state to the view model. Apple should be testing the controls that we are using, and you should be testing the custom controls you create. This means that as we bind our controls state to the view model we don't need to query the controls for their state as we should be able to access it within the view model itself. This feature tends to lending itself well to the next feature...

We can easily Unit Test the View Model

The View model has access to all the properties the views are binding to, and because of this we can have validation logic on the view model. This also makes it extremely easy to unit test the model and unit test the various states our UI can get into. I think Justin actually phrased this excellently "A good litmus test for MVVM is whether you’re able to write automated tests for your UI behavior without actually having a live UI." I completely agree with this and think it excellently encapsulates the core idea of MVVM.

Its easier to change the UI

Because the UI is just binding to the view model, this means you should be able to swap components out and just bind the apppropriate properties to the view model and your UI should work the same as before. This should also make it easier for UI designers to experiment around with different views in your app.

ReactiveCocoa: An introduction

As I mentioned ReactiveCocoa is an implementation of Reactive Extensions .NET for Cocoa. The API is not an exact mapping of the API from Rx to Cocoa as explained in the project docs. ReactiveCocoa is also built using the concept of Functional Reactive Programming.

Functional Reactive Programming (FRP) is a programming paradigm for writing software that reacts to change.

FRP is built on the abstraction of values over time. Rather than capturing a value at a particular time, FRP provides signals that capture the past, present, and future value. These signals can be reasoned about, chained, composed, and reacted to.

By combining signals, software can be written declaratively, without the need for code that continually observes and updates values. A text field can be directly set to always show the current timestamp, for example, instead of using additional code that watches the clock and updates the text field every second.

Signals can also represent asynchronous operations, much like futures and promises. This greatly simplifies asynchronous software, including networking code.

One of the major advantages of FRP is that it provides a single, unified approach to dealing with different types of reactive, asynchronous behaviors.

Lets jump right into ReactiveCocoa through a couple examples and explain what is going on.

[RACObserve(self,name) subscribeNext:^(NSString *newName){
    NSLog(@"Name changed to %@",newName);
}];
self.name = @"Hypnotoad";
self.name = @"Nibbler";

When this runs it'll give the output "Name changed to Hypnotoad" and then "Name changed to Nibbler". What we did was create a signal around a key path in self, and then subscribed to that signal and received events on the stream from that signal. Think of it this way, once we create a signal around a key path in this manner anytime the value of that key path changes the signal will see this and send a -next signal with the updated value. We automatically subscribed to this signal when we called -subscribeNext on it.

Signals only send 3 types of messages

  • next : This is how we get updated values from the stream
  • error : This is sent anytime the signal could not complete
  • completed : Sent to let you know that there will be no more signals on the stream

Lets create a signal of our own so you can see what is going on here

-(RACSignal *)urlResults {
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    NSError *error;
    NSString *result = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]
     encoding:NSUTF8StringEncoding
        error:&error];
    if (!result) {
        [subscriber sendError:error];
    } else {
        [subscriber sendNext:result];
        [subscriber sendCompleted];
    }
    return nil;
 }];
}

Although we could achieve this through other means, I wanted to create this manually. This method returns a signal which was created to get the string contents of a URL address and then return them to us. For this I used NSStrings built in method to retrieve a string from a URL. All we need to do is check to see if we have a result and if we don't then we can send -next and then -completed because we don't intend to send anymore messages.

Besides receiving updated values which we'll likely use for assignment to variables, signals also can be used in validation.

NSCharacterSet *charSet = [NSCharacterSet characterSetWithCharactersInString:@" "];
RACSignal *nameFieldValid = [RACSignal combineLatest:@[ self.usernameField.rac_textSignal, self.passwordField.rac_textSignal ]
 reduce:^(NSString *username, NSString *password) {
    return @((username.length > 0) && (password.length > 0) &&
            ([username rangeOfCharacterFromSet:charSet].location == NSNotFound));
 }];

This particular example would work on iOS if you had a Username field, password field and you wanted to know if it was filled out correctly. For the purposes of this example we will only concern ourselves with making sure the username & password has a length greater than 0 and doesn't have any spaces in the user name. The combineLatest part of the method makes sure that we get the latest values from the textfield signal, then in the reduce section we are simply returning a number (0 or 1) to indicate if this is valid. When we hook this up to the enabled property of a control we get...

RAC(self.loginButton.enabled) = nameFieldValid;

and from there on out we get a button that is automatically enabled & disabled when the correct conditions arise from the signal we binded it to. Similarly we can bind controls to a view model like so...

RAC(self.textField.text) = RACObserve(self.viewModel,title);

What is going on here is that ReactiveCocoa is implicitly setting up all the necessary infastructure to bind a field to a signal. If you expand the RAC fields you get something like...

[RACSubscriptingAssignmentTrampoline trampoline][ 
[[RACSubscriptingAssignmentObjectKeyPathPair alloc] initWithObject:self 
keyPath:@(((void)(__objc_no && ((void)self.self.resultLabel.string, __objc_no)),
 "self.resultLabel.string"))] ] = 
 [self rac_signalForKeyPath:@(((void)(__objc_no && 
 ((void)self.self.aTitle, __objc_no)), "self.aTitle")) 
 observer:self];

Be thankfull you don't have to write all that every time you wanted to bind properties in your code.

What is the ViewModel?

So i mentioned the View Model earlier as being the thing that our user interface binds its properties to as well as containing the actions that can be done to the view model and any validation logic. Lets show a simple example and get started figuring out how the VM in MVVM works. Here is a screenshot of the UI we'll work with...

And here is the ViewModel interface...

#import <Foundation/Foundation.h>

@interface CDWPlayerViewModel : NSObject

@property(nonatomic, retain) NSString *playerName;

@property(nonatomic, assign) double points;
@property(nonatomic, assign) double stepAmount;
@property(nonatomic, assign) double maxPoints;
@property(nonatomic, assign) double minPoints;

@property(nonatomic, readonly) NSUInteger maxPointUpdates;

-(IBAction)resetToDefaults:(id)sender;

-(IBAction)uploadData:(id)sender;

-(RACSignal *)forbiddenNameSignal;

-(RACSignal *)modelIsValidSignal;

@end

and the implementation

#import "CDWPlayerViewModel.h"

@interface CDWPlayerViewModel ()
@property(nonatomic, retain) NSArray *forbiddenNames;
@property(nonatomic, readwrite) NSUInteger maxPointUpdates;
@end

@implementation CDWPlayerViewModel

-(id)init {
    self = [super init];
    if(!self) return nil;

    _playerName = @"Colin";
    _points = 100.0;
    _stepAmount = 1.0;
    _maxPoints = 10000.0;
    _minPoints = 0.0;

    _maxPointUpdates = 10;

    //I guess we'll go with the ned flanders bad words
    //change this to whatever you want
    _forbiddenNames = @[ @"dag nabbit",
                      @"darn",
                      @"poop"
                      ];

    return self;
}

-(IBAction)resetToDefaults:(id)sender {
    self.playerName = @"Colin";
    self.points = 100.0;
    self.stepAmount = 1.0;
    self.maxPoints = 10000.0;
    self.minPoints = 0.0;
    self.maxPointUpdates = 10;
    self.forbiddenNames = @[ @"dag nabbit",
                          @"darn",
                          @"poop"
                          ];
}

-(IBAction)uploadData:(id)sender {
    @weakify(self);
    [[RACScheduler scheduler] schedule:^{
        sleep(1);
        //pretend we are uploading to a server on a backround thread...
        //dont ever put sleep in your code
        //upload player & points...

        [[RACScheduler mainThreadScheduler] schedule:^{
            @strongify(self);
            NSString *msg = [NSString stringWithFormat:@"Updated %@ with %.0f points",self.playerName,self.points];

            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Upload Successfull" message:msg delegate:nil
                                                  cancelButtonTitle:@"ok" otherButtonTitles:nil];
            [alert show];
        }];
    }];
}

-(RACSignal *)forbiddenNameSignal {
    @weakify(self);
    return [RACObserve(self,playerName) filter:^BOOL(NSString *newName) {
        @strongify(self);
        return [self.forbiddenNames containsObject:newName];
    }];
}

-(RACSignal *)modelIsValidSignal {
    @weakify(self);
    return [RACSignal
            combineLatest:@[ RACObserve(self,playerName), RACObserve(self,points) ]
            reduce:^id(NSString *name, NSNumber *playerPoints){
                @strongify(self);
                return @((name.length > 0) &&
                (![self.forbiddenNames containsObject:name]) &&
                (playerPoints.doubleValue >= self.minPoints));
            }];
}

@end

A short note about @weakify(self); and @strongify(self);, this is one of the things you can do in addition to using __weak id bself = self; in your apps to avoid retaining self. This particular bit of code is was originally from libextobjc and then incorporated directly into ReactiveCocoa itself. In particular this has the same effect of creating a weak reference to self. I like this approach because you just keep using self.[property]... in your code and you don't have to constantly remember to create a bself variable. Check out EXTScope.h in libextobjc or RACEXTScope.h in ReactiveCocoa.

as you can see its relatively simple because we are only really concerned with a couple properties related to the player. The other properties are for controls to bind to and for some validation. We also have a single action method and a couple signals. The one thing you'll notice is the View Model has no clue what the UI it'll bind to is like at all. This is great because it means you have flexibility in what you bind things to and you can hook up to the view model in ways that make sense for the class thats binding to it.

Now lets look in our ViewController and how it is using these properties and signals...

__weak CDWViewController *bself = self;

To make sure we don't retain self in our blocks we need to use a weak reference. The ReactiveCocoa Project also has @weakify and @strongify for doing this in blocks, but i'll let you investigate that and see if you want to use it.

//Create the View Model
self.viewModel = [CDWPlayerViewModel new];

obviously start with creating a ViewModel instance

//Start Binding our properties
RAC(self.nameField.text) = [RACObserve(self.viewModel,playerName) distinctUntilChanged];

[[self.nameField.rac_textSignal distinctUntilChanged] subscribeNext:^(NSString *x) {
    bself.viewModel.playerName = x;
}];

The first control is the UITextField for the player name, so we need to bind its text property to the view models playerName property. We also need to make sure we update the view model with updates from the text field. This ensures that the text field receives any updates from the view model and also makes sure that the view is updating the player name property on the view model.

//the score property is a double, RC gives us updates as NSNumber which we just call
//stringValue on and bind that to the scorefield text
RAC(self.scoreField.text) = [RACObserve(self.viewModel.points) map:^id(NSNumber *value) {
    return [value stringValue];
}];

We need to bind the labels text property to the view models points property. The view models points property is a double, but ReactiveCocoa gives us updates to this as NSNumber's so we need to map this to a NSString which the label can use.

//Setup bind the steppers values
self.scoreStepper.value = self.viewModel.points;
RAC(self.scoreStepper.stepValue) = RACObserve(self.viewModel,stepAmount);
RAC(self.scoreStepper.maximumValue) = RACObserve(self.viewModel,maxPoints);
RAC(self.scoreStepper.minimumValue) = RACObserve(self.viewModel,minPoints);

Simple binding and setup. Give the stepper the initial value from the view model and bind the properties (stepValue,min,max) to the view model.

//bind the hidden field to a signal keeping track if
//we've updated less than a certain number times as the view model specifies
RAC(self.scoreStepper.hidden) = [RACObserve(self,scoreUpdates) map:^id(NSNumber *x) {
    return @(x.intValue >= bself.viewModel.maxPointUpdates);
}];

//only take the maxPointUpdates number of score updates
[[RACObserve(self.scoreStepper,value) take:self.viewModel.maxPointUpdates] subscribeNext:^(id newPoints) {
    bself.viewModel.points = [newPoints doubleValue];
    bself.scoreUpdates++;
}];

We'll enforce a rule from the view model that at any given time you can only update the points 10 times. To do this I created a NSUInteger property (in fact the only property we ever actually add to the view controller.) Then bind the hidden property to a signal which reduces to a 0 or 1 based on if the number of times we've updated is greater or equal to the number of times we've updated the points. So as soon as it hits the number we want this will return 1 and flip the hidden property to YES. To update the points we subscribe to the value property of the stepper and anytime it updates we update the view model and increment the player points.

//this signal should only trigger if we have "bad words" in our name
[self.viewModel.forbiddenNameSignal subscribeNext:^(NSString *name) {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Forbidden Name!"
                                                    message:[NSString stringWithFormat:@"The name %@ has been forbidden!",name]
                                                   delegate:nil
                                          cancelButtonTitle:@"Ok"
                                          otherButtonTitles:nil];
    [alert show];
    bself.viewModel.playerName = @"";
}];

If you remember the view model has a validation signal which indicates if any names given are forbidden. My list is really bad and not representative of what I personally think are bad words by any stretch of the imagination. The beauty of this is that we don't need to know any of the details of what the view model thinks is a "bad word", but it can just provide a signal to indicate that it thinks something should be forbidden. The view model can provide signals for many things like this that it thinks are important to let you know about it. In this case all we've decided to do is show an alert view and reset the player name.

//let the upload(save) button only be enabled when the view model says its valid
RAC(self.uploadButton.enabled) = self.viewModel.modelIsValidSignal;

Another signal that the view model provides to us is a signal letting us know if the view model as it exists it valid or not. In this case i've hooked this signal to the enabled property of the upload button. So we should not be able to upload the player stats if the state of the view model is bad. The signal here is simple

-(RACSignal *)modelIsValidSignal {
    @weakify(self):
    return [RACSignal
            combineLatest:@[ RACObserve(self,playerName), RACObserve(self,points) ]
            reduce:^id(NSString *name, NSNumber *playerPoints){
                @strongify(self);
                return @((name.length > 0) && (![self.forbiddenNames containsObject:name]) && (playerPoints.doubleValue >= self.minPoints));
            }];
}

So for the purposes of this simple demo, we are just concerned if the name length is greater than 0, the name isn't in the forbidden names and the points are greater than the minimum. Really we should be concerned with more, but I won't extend it further. We could even just put the forbidden names signal in if we changed it to use map and return a NSNumber with 0 or 1 and so we could use it here inside this signal.

//set the control action for our button to be the ViewModels action method
[self.uploadButton addTarget:self.viewModel
                      action:@selector(uploadData:)
            forControlEvents:UIControlEventTouchUpInside];

The button is set to trigger the View Mode's upload data action. This method in the sample code simulates uploading something then presents an alert view letting you know about the success of uploading.

//we can subscribe to the same thing in multiple locations
//here we skip the first 4 signals and take only 1 update
//and then disable/hide certain UI elements as our app
//only allows 5 updates
[[[[self.uploadButton rac_signalForControlEvents:UIControlEventTouchUpInside]
   skip:(kMaxUploads - 1)] take:1] subscribeNext:^(id x) {
    bself.nameField.enabled = NO;
    bself.scoreStepper.hidden = YES;
    bself.uploadButton.hidden = YES;
    }];

Here since there is already signals enabling the button now the number of uploads need to be limited. This is subscribing to the signal for the UIControlEventTouchUpInside event and on the nth update where n is kMaxUploads. On the nth update the namefield is disabled, and the score stepper and upload buttons are hidden.

All of this results in a UI that just binds its properties to a view model, sets its actions to actions on the view model and receives signals from the view model indicating things of interest. I admit this particular example is a bit weird, but it demonstrates using a view model and using the basic aspects of ReactiveCocoa. There is a lot more to ReactiveCocoa in particular that I haven't shown here for the sake of not introducing too many concepts all at once. Additionally we could build some better view models for dealing with networking code and could deal with child view controllers, but that will have to wait for another article.

So what have we seen here?

  • MVVM stands for Model-View-ViewModel
  • The View model contains things like properties to bind to, validation logic and actions to be done to the view model
  • The View Model should not know anything about the UI that will bind to it
  • ReactiveCocoa is an implementation of many of the API's in Microsofts Reactive Extensions for .NET in Cocoa
  • We learned how to bind & subscribe to properties
  • We learned how to create signals

The biggest thing you can see with reactive cocoa is that all the code and signals are just reacting to events. When we chain these responses together and filter events properly we heavily reduce the need to create tons of variables and methods just to keep track of the events going on. This leads to more reliable code and with the view model we can easily test it and simulate a UI without actually having a live UI in our app.

The complete source code thats shown here is located here https://github.com/Machx/MVVM-IOS-Example.

So check out ReactiveCocoa on github, and I've provided some helpful links at the bottom to help understand these concepts. If people want i'll dive deeper into ReactiveCocoa in later articles.

Update Since first publication this article has been updated to address a couple minor issues

  • Make sure we don't retain self in blocks
  • Update a piece of code where -map could simply be used in place of -combineLatest:reduce:
  • The github sample code repo code has been updated

Thursday, August 30, 2012

Cover up those ivars

It all started with a tweet a couple mornings ago...

I completely agree with this. Objective-C has evolved over time from where everything was public and had to be included in the header files to now where only the bare minimum needs to be exposed in the header file. Now its completely bad practice to put anything in the header file that doesn't need to be exposed.

There are several Good reasons for this

When designing a class from an external point of view all I should really need to know is what your class name is and what its api's are, what I need to pass them, if anything, and what they return. When you see internal implementation details and variables there is a temptation to use them. This is bad, because you as a consumer of the class should only be concerned with what the class promises to do, and when you reach into the class to access stuff that was never really intended to be exposed you will be bitten with bugs if the implementation details ever change.

I think of methods as fulfilling contracts, I agree that I will pass them what they need if they accept arguments and they agree to return something or cause some effect (i.e. NSLog() piping text to console,etc.) As a writer of classes in a Framework, i've never been concerned about completely changing the details of how the classes work, because I have Unit Tests that test these contracts with my methods to make sure they work as advertised. It's also just cleaner design-wise and the more you can leave out of your header file the better, it makes the header file easier to read and scan for what I am looking for.

How do you do this?

Ideally the rule of thumb should be this: Expose as little as you possibly can in your header file!

This means several things: (1) If you can not declare methods in the header and instead declare them in a class extension in the implementation file(.m) do it (2) If you need to expose properties make them readonly if possible (3) if you need to have ivars declare them right after the @implementation declaration. This doesn't mean hide everything all the time, but generally I like to think of this as designing a class and then only putting in the header file what needs to be exposed to make the class useful.

Here is a class extension

@interface MyClass()
-(NSUInteger)somePrivateMethod;
@end

Here is an example of declaring a method in a class extension. Class extensions are like categories, except that a class extension really just extends the @interface section of a class declaration in another location, so unlike a category if you declare a method and forget to implement it, the compiler will warn you.

If you need to declare properties try to hide them in your extensions, if you need to make them public, make them readonly if possible. This still gives people access to them, but prevents them from doing anything with the variables and screwing up your class. Like so

@interface MyClass : NSObject
@property(readonly, retain) NSString *currentPath;
@end

then in your implementation file you can redeclare it with read & write capabilities. 

@interface MyClass()
@property(readwrite, retain) NSString *currentPath;
@end

This way, publicly you can give people access to bits of information about your class, but only have rights to change them in the implementation. You can also use these extensions to declare properties that are only used in the implementation file.

Another way of declaring variables that didn't exist till very long ago is to do so only after the @implementation declaration like so

@implementation MyClass {
    NSString *internalVar1;
    NSNumber *internalVar2;
}

this is equivalent of 

@interface MyClass : NSObject {
    NSString *internalVar1;
    NSNumber *internalVar2;
}

@end

 except now that this isn't in your header file polluting it. 

How do my Subclasses use these vars?
A legitimate question that someone asked me this afternoon was essentially "If my class hides all these variables in extensions, how could I ever use them in subclasses?" Thats very worth asking. In this case instead of declaring these variables in a class extension in the implementation file you would create a "MyClass_private.h" file where the class extension is. Then your .m file and any interested subclasses can import this header in their implementation files and use it. I would even go so far to write methods into your class such, that to the extent possible, you don't even need to access these internal only vars in your subclasses. 

Why Does this matter if its code just for me?
A couple people asked me this. All I can really ask is why would you write bad code just for yourself? Nobody writes perfect code, well maybe except for me(I kid I kid), but you're not me. But why would you write intentionally bad code for yourself? I always write my classes using these principals, even for stuff thats just for play. Well designed classes means not having to spend tons of time ripping & rebuilding them just to make them presentable later on, it means you can instantly take them and use them in anything without much worry. 

In Conclusion
The less you expose in your headers the cleaner they are, they become easier to read, they don't expose anything that could become future bugs or crashes later on. This makes it easier for you to completely rewrite or change implementation details at will.  

Follow Up
Rich in Comments makes a good point about also putting IBOutlets & IBActions in class extensions. When I said to hide vars and methods I also meant these. The IB component in Xcode iirc didn't see those initially. However for a while now it can see IBOutlets and IBAction methods declared in Class Extensions.

When I said that some of this is "new" in this article, generally I mean in the grand scheme of Objective-C's history at Apple it's new.

Eric made a good point, and I saw and forgot about this in the WWDC videos, that in LLVM Compiler 4.0 its no longer necessary to declare private methods as the compiler scans the implementation for those methods and thus won't give you an error if you forget to declare it.

I was asked if I put my ivars in a class extension or declare after the implementation, generally I declare them in my class extensions.

Tuesday, January 31, 2012

Clang Source Annotations

Recently I was faced with a dilemma. I was writing code I needed, and then I triggered a Clang Static Analyzer issue. Here is the code a category on NSColor, see if you can figure out whats wrong with it from a Static Analyzer perspective...

-(CGColorRef)cw_cgColor { 
NSColor *nscolor = [self colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
CGFloat components[4];
[nscolor getRed:&components[0] green:&components[1] blue:&components[2] alpha:&components[3]];
CGColorSpaceRef space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
CGColorRef cgColor = CGColorCreate(space, components);
CGColorSpaceRelease(space);
return cgColor;
}

While all the code here is perfectly valid, and converts a NSColor to a CGColorRef just fine, the Clang Static Analyzer will trigger an issue on the last line. Why? Because of this

CGColorRef cgColor = CGColorCreate(space, components);

We've created a Core Graphics or Core Foundation object with a create method which means it needs to be freed later on. However we are just returning that object in this method so the compiler has no way to really know that we will free this object later on. If only there was a way to let the Clang Static Analyzer know that whoever calls this needs to free the object and therefore this code isn't leaking.  Well there is, its called Source Annotations. All I did was add CF_RETURNS_RETAINED to the end of the method declaration in the header file and the Clang SA issue went away. So now the declaration looks like

#import <AppKit/AppKit.h>
@interface NSColor (CWNSColorAdditions)
-(CGColorRef)cw_cgColor CF_RETURNS_RETAINED;
@end

This says to the Clang Static Analyzer whoever calls this method will be receiving a Core Graphics object thats retained and therefore the caller needs to free it when its done. I could have also put 'create' or 'copy' in the name of the method, but I wanted it to be nearly identical in name (remember always prefix your names of methods where your extending Apple classes, cw_ is mine in this case) to the name of the CGColor property on UIColor. This is not the only annotation, but if you haven't seen Clang Annotations, you should see whats available for when you run into issues trying to convey to the Clang Static Analyzer what your code is doing.

Clang Static Annalyzer Source Notations http://clang-analyzer.llvm.org/annotations.html The above code is from my Zangetsu Framework

Enjoy.

Thursday, April 07, 2011

Singletons: You're doing them wrong

This post feels a bit odd, as generally I fully agree with Dave Dribin on how wrong singletons are and that you should avoid them if possible. However on Stack Overflow i've seen far too many people write bad code that is horrible for several reasons.

Basic Example

Singletons are fairly easy to create. Here is a basic example...

+(MyClass *)singleton {
 static MyClass *shared = nil;
 
 if(shared == nil) {
  shared = [[MyClass alloc] init];
 }
 return shared;
}

However this is wrong on several levels. Firstly, this isn't thread safe, so what happens if multiple threads all try to access this at the same time? There is no reason 1 thread couldn't be in the middle of allocating the object while the other one is trying to access the object. This is actually what Apple shows in its documentation.

If you must use singletons, use dispatch_once()

dispatch_once() solves the problem of safely being able to create a singleton in that (1) it guarantees that the code in the block will only be called once for the lifetime of the application (2) its thread safe as I noted in a previous article and (3) its faster than other methods like using @synchronize(),etc...

"If called simultaneously from multiple threads, this function waits synchronously until the block has completed."

So you should be writing it like this...

+(MyClass *)singleton {
 static dispatch_once_t pred;
 static MyClass *shared = nil;
 
 dispatch_once(&pred, ^{
  shared = [[MyClass alloc] init];
 });
 return shared;
}

This is a safe way to create a singleton. There is no way to accidentally create it twice, its fast and it is thread safe.

Conclusion

Avoid singletons if at all possible because it is easy to abuse them. Unlike Dave Dribin I don't think they are evil, but I really try and avoid them when possible. If you must create them, do it right and don't create them like the first example, use dispatch_once(). It is less code and the correct way to do it.

Wednesday, March 09, 2011

Xcode 4 Keyboard Shortcuts now available!

Xc4 kbsc

The Xcode 4 Keyboard Shortcuts are now available. I've decided to make forking it and creating your own version easier by putting it up on Github. This will make it easier to browse forks and merge new formats in. Additionally it makes it easy to have a consistent go to place that doesn't change for updates to the shortcuts.

You can download the Xcode 4 keyboard shortcuts here:
Xcode Keyboard Shortcuts Repository
Xcode 4.0 Keyboard Shortcuts (Blue)
Xcode 4.0 Keyboard Shortcuts (Black and White)

Believe it or not I got a few requests to actually charge for the shortcuts. For something like this, it is just not my style, but if you want to contribute maybe so I can afford some better tools than pages or spend more time on maintaining them and updating them faster, then you can donate whatever you feel like here http://pledgie.com/campaigns/14858.

Wednesday, February 23, 2011

Practical Design Patterns with Blocks and Grand Central Dispatch

Introduction

When Mac OS X 10.6 was introduced, the Mac got a very powerful duo of developer tools that made development on a lot easier. With iOS 4.0 developers finally got access to these tools as well. These tools are known as Blocks & Grand Central Dispatch. This article is not an introduction to these technologies as i've already covered them before here http://cocoasamurai.blogspot.com/2009/09/guide-to-blocks-grand-central-dispatch.html. What this article is, is a introduction to some design patterns I use and have seen other developers use in 1 handy article.
Many of the design patterns I am displaying here are actually in use in my Zangetsu Framework which is open source under the MIT License on Github.
Iterative Callbacks
/**
 Ruby inspired iterator for NSArray in Objective-C
 */
-(NSArray *)cw_each:(void (^)(id obj))block
{
    for(id object in self){
        block(object);
    }
 
    return self;
}
Blocks are really good for doing callbacks and one of the things you can do already is enumeration. Now while Objective-C is definitely expressive with high level english like syntax, sometimes it is unnecessarily verbose in my opinion. When I started reading through my Ruby 1.9 book one thing I loved was ruby's enumeration with each. It's so simple and while it could be slightly more verbose it's succinct enough. So I decided to implement each in Objective-C with blocks since I could actually make it work. The result is what you see above.
Additionally you can use grand central displatch and make this asynchronous.
-(NSArray *)cw_eachConcurrentlyWithBlock:(void (^)(id obj))block
{
    dispatch_group_t group = dispatch_group_create();
 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 
    for(id object in self){
  
        dispatch_group_async(group, queue, ^{
            block(object);
        });
    }
 
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    dispatch_release(group);
 
    return self;
}
In this example I am using dispatch groups and getting a reference to a global queue and then basically enumerating over the objects and then calling dispatch_group_wait() to make sure that all the blocks complete. This type of thing is great when you want to be both asynchronous, but also ensure that the method itself is synchronous.
/**
 Simple mapping method using a block
 */
-(NSArray *)cw_mapArray:(id (^)(id obj))block
{
    NSMutableArray *cwArray = [[NSMutableArray alloc] initWithCapacity:[self count]];
 
    for(id obj in self){
        [cwArray addObject:block(obj)];
    }
 
    return cwArray;
}
Here is a good example of putting that callback capability to good use. In this example I wanted to map one array to another one. This is basically exactly the same as my cw_each method above except that inside this method I am creating an array that the new (mapped) array is being stored in and returning an object from the block. If you wanted to you could be selective in mapping an array to another by simply checking that the object returned from the block is not nil and only then adding it to an array you are mapping to.
Enclosing Blocks
Another clever use for blocks is to enclose them in between other code for various purposes. For example in this case I was experimenting with only executing a block when I am building debug code. So instead of doing...
#ifdef DEBUG
    NSString *myString = ...
    //do something with string
#endif
I think this is more clear and less cluttered
//in .h
typedef void (^DebugBlock)(void);
void CWInDebugOnly(DebugBlock block);

//in .m
void CWInDebugOnly(DebugBlock block)
{
#ifdef DEBUG
    block();
#endif
}
This way in code I can do
CWInDebugOnly(^{
    NSString *myString = ...
    //do something with string....
});
This relies on DEBUG being defined only in your debug builds. I have this set up to only be defined in my Debug and Analyze configurations. I've also seen Mike Ash cleaverly do this exact same thing with NSAutoreleasePools like so...
//in .h
typedef void (^VoidBlock)(void);
void inAutoreleasePool(VoidBlock block);

//in .m
void inAutoreleasePool(VoidBlock block)
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    block();
    [pool drain];
}
Completion Blocks
Completion Blocks are especially good things to have around. They are very useful on objects that are performing some operation, usually asynchronously, and we would like to know when the operation has been completed. We may or may not care about the implementation details, but we need a mechanism to do something when this is done. This is where completion blocks are excellent helpers. In the past before blocks we may have used notifications or delegates and created methods especially to deal with this 1 specific application. Now it's as easy as assigning a block as a variable and executing it when you are done. One prime example of this is NSOperation. You can create it, add it to a queue, and go on and do other things, and once the operation is done it executes your completion block. These completion blocks are also excellent because we can do these things on threads in grand central dispatch and simply in the completion block dispatch back to the main thread and update the user interface
NSData *data = //..data from a file or internet
MyOperation * operation = [[MyOperation alloc] initWithDataToParse:data];

[operation setCompletionBlock:^(NSString *result){
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        [self updateUIWithString:result];
    }];
}];

[queue addOperation:operation];
This code is easy to read and follow what it is doing. Let's see how we can do this in our classes.
//.h
typedef void (^TaskCompletionBlock)(void);

@interface MyClass : NSObject {}
@property(nonatomic,copy) TaskCompletionBlock block;
-(void)doTask;
@end

//.m
@implementation MyClass

@synthesize block;

-(id) init
{
    self = [super init];
    if(self){
        //
    }
    return self;
}

-(void)doTask
{
    //do some task here...

    if(self.block) {
        self.block();
    }
}

@end
Dispatch_Once
Out of all the API calls I saw in grand central dispatch the one that initially impressed me least was dispatch_once. However after reading its documentation and using it a bunch I realized how useful this one API call is. Not only it is a dead simple way to ensure that code only gets executed once, but it is also thread safe. From the API...
"If called simultaneously from multiple threads, this function waits synchronously until the block has completed."
This means its perfectly safe to run code like this from multiple threads...
+(NSString *)coreDataKeyNameForWebAPIKey:(NSString *)name
{
    static dispatch_once_t dictPrec;
 
    dispatch_once(&dictPrec, ^{
  
        coreDataKeyMappings = [[NSDictionary alloc] initWithDictionary:NSDICT(
            kCDEntityNameKey,           kWebEntityNameKey,
            kCDEntityDateKey,           kWebEntityDateKey,
            kCDEntityTimeStampKey,      kWebTimeStampKey,
            KCDEntityUpdateKey,         kWebEntityUpdateKey)];
    });
 
    NSString *translatedKey = [coreDataKeyMappings valueForKey:name];
 
    return translatedKey;
} 
Conlcusion
Grand Central Dispatch and Blocks are just awesome. Even just blocks by itself makes many things possible that weren't before. With grand central dispatch and blocks many problems that have been traditionally associated with multithreading go away. These 2 technologies don't eliminate all these problems, but they certainly do make them much more manageable.

Tuesday, December 28, 2010

Objective-C Memory Management & Garbage Collection

This article started out as a presentation I did for the Des Moines Cocoaheads.

Introduction

Objective-C Memory Management is something i've seen new people to Cocoa & Objective-C mess up in ways I could just not conceive of on my own. In reality Objective-C memory management is not that hard. You simply need to be aware of some rules and follow a couple of good development practices. Good memory management practices are a good thing to follow on any platform. You don't want to be known as "that" app that hogs lots of memory, I have switched to alternative apps a couple times because the apps I was using were fine, but consumed far too much memory. Especially on iOS you need to follow good memory practices, because otherwise you'll be struggling to deal with low memory alerts and the possibility of your app being killed by iOS.

Objective-C Retain Count

Objective-C in retain count mode (not using garbage collection) is a simple idea. When you explicitly allocate an object it gets a retain count of 1 and when you call release or autorelease on an object it's retain count gets decremented and then the object will be collected. It is the only mode available on iOS Devices and has been in use on Mac OS X since the beginning of the OS.

NSObject *object = [[NSObject aloc] init]; //retain count 1
[object release]; //retain count 0

When a object gets released -dealloc gets called on an object and its memory will be reclaimed. It's important to note that you never call dealloc on an object directly. In fact in all my time as a Cocoa Developer I've heard only 1 legitimate use of calling -dealloc on an object directly, I won't say what it is, but needless to say you would have a lot of Cocoa/Objective-C experience behind you before you would even conceive of doing this. In the same area as -release there is also -autorelease. -autorelease is the same as -release except that it'll perform the release in the future. This works great because with this an object you know you need to release in the future can be taken care of at the beginning of a method or section of code.

-(void)doFoo:(BendingUnit *)bender
{
 if(flexo)
  [flexo autorelease]; //will be sent release later
 ...


Owning an Object
In all these cases when we explicitly perform an -alloc we "own" the object, and when we call -release or -autorelease we relinquish ownership. If you call a method whose name contains 'alloc','new' or 'copy' or if you send a retain message to an object you now own the object and it is your responsibility to send it a -release or -autorelease at an appropriate time. An example of assuming ownership of an object...

-(NSInteger)numberOfInstancesOfString:(NSString *)pattrnString
{
 NSString *patternString = [[pattrnString retain] autorelease];
 NSInteger count = 0;
 // do some stuff here with the string return count;
}

In the above example we are doing something very wise. We are passed in a NSString object which may live beyond the scope of our method. So to ensure that the string lives throughout our method we are calling -retain on the string object and -autorelease on it as well so that at the end of the method it'll be restored to the state it was originally in. If this is a normal string object (retain count 1) then all we are doing is incrementing it's retain count to 2 and then at the end of the method it's retain count will be back at 1. However if we are in the middle of executing this method and somewhere else this object gets a release message then we are ensured to be able to use the object for the lifetime of the method and then the passed object will be released. Note that by calling retain on the string object we assumed ownership of the object and then also did the responsible thing and called autorelease to relinquish ownership of it at the end of the method. What happens we we don't follow the rules?

-(void)dooFoo
{
 NSString *myString = [[NSString alloc] initWithString:@"Good News Everyone!"];
 //... do some stuff
 //... oh noes we are at the end of the method and never sent release to mystring!
}

Oh Noes! At the beginning of this method we create a NSString pointer and explicitly allocate memory for a NSString object and initialize it with a NSString object. The method does some things and then it goes away. However the memory that we allocated is still there, but we no longer have a reference to that memory leaving it forever uncollectible (except under Garbage Collection.) This is a memory leak, it's memory we asked the operating system to set aside for us that we can not reclaim.


NSAutoreleasePool

Autorelease pools are a place where you can collect objects sent an autorelease message and clean them up by sending an NSAutoreleasePool a drain message. When you are running an application based on AppKit, the Cocoa Framework automatically creates a NSAutoreleasePool instance for you and drains it upon your application quitting. You can setup and drain a autorelease pool easily.

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *temp = [NSString stringWithString:@"Name:"];
NSNumber *tempNumber = [NSNumber numberWithInt:55];
[pool drain]; //collects temp & tempNumber

You can also do AutoreleasePools within other autorelease pools
int main(int argc, const char **argv[])
{
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSArray *files = //fileArray...
 for(NSString *file in files) {
  NSAutoreleasePool *innerPool = [[NSAutoreleasePool alloc] init];

  NSError *fileError = nil;
NSString *file = [NSString stringWithContentsOfFile:file encoding:NSUTF8Encoding error:&error];
  //process file...
  [innerPool drain];
 }
 [pool drain];
}

This can be convenient, especially in iOS to allocate a bunch of objects and free them as soon as possible with an autorelease pool to keep memory pressure down. In some cases they are completely necessary if you intend to say work with Foundation in a command line tool you have to explicitly create an autorelease pool, the same goes for NSOperations main method (except for Garbage Collected apps where this is done automatically for you.)


Coding Horrors

A while before I made a presentation from the same content that is in this article I asked on twitter for some ways people had seen memory abused in Objective-C. From the responses I got back and some things I have heard from various people I won't name here a lot of people have abused Objective-C memory in odd ways. I want to feature some of them here in the hopes that you will never commit these atrocities yourself.


Exhibit 1
-(void)dealloc
{
 while([myObject retainCount] != 0){
  [myObject release];
 }
 [super dealloc];
}

This is wrong on all sorts of levels. Putting this in your code is a sure fire way to show someone how little you understand about Objective-C. First of all let me say this morvo_retain_count.png

If you've been dealing with Objective-C for a while you know that you shouldn't be using the value of retain count, it never actually goes down to zero and you should never be testing against zero anyway. In fact the only reason retain count is still in the Cocoa framework is for legacy reasons and there are a lot of developers petitioning Apple to remove retain count from Cocoa entirely. In any case, the above code should only have 1 release per object in it. If you have objects that have a retain count of 1 or more by the time they've hit this method then you have not properly released or autoreleased the object somewhere else.


Exhibit 2
MyObject *obj = [[MyObject alloc] init];
//do stuff with obj...
[obj dealloc];

Again you shouldn't call dealloc on an object directly. In fact in all of our Cocoaheads group only Eric Rocesecca (a longtime mac veteran, formerly of startly (quickeys) fame) could only come up 1 use for sending dealloc directly to an object for 1 specific case. I won't even go into that specific case, because it's really a specific niche case & beyond the scope of this article.


Exhibit 3
MyClass *obj = [[[[MyClass alloc] init] autorelease] retain];
//do stuff with obj...
[obj release]; 

In this specific example by itself the extra autorelease and retain are just extra garbage at the end since you could just have the alloc and init and do the release and have the exact same effect. This code was shown to me to be in some of Facebooks open source code.


Exhibit 4
MyClass *myObj = [[MyClass alloc] init];
//...do stuff
[myObj release];
[myObj release]; 

If you have multiple retains/releases in 1 place its a very strong signal that you have not done a proper retain release somewhere else. You should really examine your code to make sure you should be doing retain and release elsewhere.


Exhibit 5
NSAutoreleasePool *pool = //...//... do stuff
if(num != kMax)
{
 NSAutoreleasePool *pool2 = //...
NSString *myStr = //...
 //do stuff with myStr
 [pool2 drain]
}
[pool drain]; 

This is something that I could not have conceived on my own. If you are using a lot of autorelease pools and using them as a fix for memory leaks your doing something wrong. There is a legitimate use to using autorelease pools every so often as a means of releasing memory pressure, especially if you are allocating a bunch of objects at once on iOS, but you shouldn't be putting them everywhere because you detect a memory leak.


Exhibit 6
[self dealloc];
while([self retainCount])
 [self release]; 

Similar to Exhibit #1, except with 2x the stupidity. So how do we find what's wrong with our apps?

instruments_memory.png

There are several things you can do
1. Turn on the Clang Static Analyzer, I basically duplicated by debug configuration and named it Analyze and then flipped on the "Run Clang Static Analyzer" checkbox so it's always running the clang static analyzer all the time. The Clang static analyzer will point out many (but not all) places where it can see you are doing something wrong with memory
2. Periodically profile the memory use of your app
3. Run Zombies instrument on your app to track down messages sent to deallocated objects

Objective-C Garbage Collection with AutoZone (libAuto)

Starting in Mac OS X 10.5 we got automatic memory management on Mac OS X with AutoZone (aka libAuto) with 2 collection modes generational and full. Starting in Mac OS X 10.6 we got an additional mode called local. Garbage Collection works on an entirely different principal than retain count. Essentially what you are doing in garbage collection mode (gc) is trading a little bit of cpu time for the sake of letting libauto collect objects that are out of scope and no longer referenced. At this time garbage collection is only available on the Mac. There has been speculation on when it might be made available on iOS, but I suspect that it'll only become available once the low end of all supported iOS devices are running at least the Apple A4 chip, which means the iPhone 3G and iPhone 3GS would all need to be phased out before this is feasible.
Apple has described AutoZone as
"libauto is a scanning, conservative, generational, multi-threaded garbage collector. "
This means several things. The basic principal of libauto is that from time to time it will scan the memory in use by your garbage collected (gc) app and collect out of scope memory. It is conservative in that Apple has said that when big events (like a user begins typing, massive cpu starts going on, etc.) libauto will just back out and stop collecting rather than possibly slow your application down during critical events. The generational part of this is actually how libauto began scanning your app when version 1.0 came out in leopard, it had 2 modes generational (intended to run frequently) and full (slower and to be run less frequently than generational) and now in 10.6 Snow Leopard we have local. I'll go into how these modes work later on. LibAuto is also language agnostic, it is not intended to just work with Objective-C & C, it is also in use in Ruby via MacRuby right now. Additionally libAuto is open source you can browse the source code from here http://opensource.apple.com/source/libauto/libauto-141.2/ and download a zip file from http://opensource.apple.com/release/mac-os-x-1065/.

Garbage collection is nothing new. Many other programming languages such as Ruby, Javascript, Python & Java have had garbage collection for a long time now, but no 2 garbage collectors work exactly the same. When we go into using garbage collection suddenly having to remember your retain & release messages become a thing of the past, instead you become concerned with having references to all objects you need and if those references are strong or weak. Many people have asserted that the same apps under garbage collection are generally less crash prone. Many apps already use Garbage Collection such as Xcode, Interface Builder, Mac OS X System Apps, Rapidweaver, etc..

How libAuto works

libAuto works on a fairly easy concept, at various points during your applications run on a background thread it will scan your applications memory for out of scope memory and collect what it can. You can think of it on a simple level like so
gc-diagram-1.png
We have an application with many points of memory allocated and some that have been allocated, but are no longer referenced by anything. Additionally I put in a weak reference in this diagram which I will go into more detail soon. What libAuto does is scan your application for root objects and then follows the strong references from those objects to all the other objects it can reach. When it's done it knows all the objects that are reachable from the root objects in the application and marks all the non reachable objects for collection. LibAuto then comes in and collects them. It has 3 modes it works in when scanning your memory and collecting objects.

Generational Mode
This is the mode that was used most often on Leopard. It works on the assumption that most objects are temporary and die young, and so the collector will try and focus on the young objects and not the long lived older objects in the app which have less likelihood of needing to be collected.

[NSDateFormatter setDefaultFormatterBehavior:NSDateFormatterBehavior10_4];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:dateFormat];
NSDate *returnedDate = [formatter dateFromString:dateString];

return returnedDate;

In this example the purpose of this code is to return a NSDate object. However in the process we create and allocate a NSDateFormatter object. The DateFormatter object is only there temporarily for the purposes of being able to set a attribute on it and then have it create another object from that (our NSDate object) and then we basically just ditch the NSDateFormatter object. When the garbage collector comes along it will notice that the NSDateFomatter was allocated and collect it. You probably do this a lot in your code, basically creating temporary objects in the process of accomplishing the task you are trying to achieve.


Full Mode
Full mode pretty much works as you would expect, it runs through all memory on your application and does a thorough collection. It takes the longest amount of time and so therefore doesn't run as often compared to the other modes.
Up until 10.6 these were the only 2 modes in libAuto. In 10.6 we gained a new mode called local.


Local
local mode works on an entirely different principle than the other 2 modes shown so far. This mode only scans 1 threads stack for variables between 1-96 bytes which is supposed to account for a majority of the objects in use according to Apple. Because it's not scanning your whole app and is only focusing on 1 thread it is much quicker than the other 2 modes. It will not scan Core Foundation objects which have a retain count of 1, you'll need to do a CFRelease on Core Foundation objects to make them eligible for collection.

Working with the Garbage Collector

Now we have a basic understanding of how the garbage collector works, but there are some things we still need to examine before we really have a full understanding of how to work with the garbage collector.


How to trigger the Garbage Collector
The garbage collector class is NSGarbageCollector. The 2 most common methods you will probably use are -collectIfNeeded and -collectExhaustively. The idea is that you being the architect of the app you are working on, know the best points when your application is running to trigger the collector. So for instance you may trigger a bunch of code to be run on startup in -awakeFromNib and you know 1 or a few possible points at which the arc of events in the apps startup will end and at those points you may wish to signal to the garbage collector that you have good points at which nothing is going on and the garbage collector can go through your app and collect memory.

-collectIfNeeded - Use this to suggest to the garbage collector that now is a good time to go and collect memory in the application
-collectExhaustively - Use this to force the garbage collector to collect memory in the application

Again even though you may suggest to the garbage collector that it should collect memory it may at anytime stop collection because of things like the user beginning to interact with your application.


Foundation Tools
In Cocoa apps the garbage collector thread is automatically started for you. However in foundation tools you need to manually start up the garbage collector by calling objc_startCollectorThread(). You can also use the method objc_collect(OBJC_COLLECT_IF_NEEDED) to trigger the collector. Apple also suggests if you do this that you call objc_clear_stack() to make sure nothing is falsely rooted on the stack when doing foundation tools.


__weak
The __weak qualifier is needed to solve a very important problem. If you have 2 objects pointing to each other and at least 1 of those objects has a strong reference to it, then those 2 objects will never go away because as far as the garbage collector is concerned they are reachable through root objects & strong references and therefore not eligible for collection. By default all references are strong references so simply having a pointer to other objects makes them visible to the garbage collector and thus not eligible for collection.
Screen shot 2010-12-22 at 2.06.47 PM.png
These are both objects which have valid strong pointer references. The 2nd window may have had another object reference it at some point in time but that object stopped referencing it and now you have a pointer to it, but you don't necessarily need to keep that reference alive. __weak solves this by allowing you to still have a pointer to the object, but qualifying it with weak so it just nils out when it goes away
gc_windows2.png
this way with weak references the 2nd window becomes eligible for garbage collection, you still have a reference to that object, and when you try and send messages to it they just go to nil  and if you check that pointer you'll see it points to nil assuming it has been collected. This has other benefits, in Mac OS X 10.6 and later NSNotificationCenter is weak referenced so you no longer need do to the following in your code

[[NSNotificationCenter defaultCenter] removeObserver:self
      name:kObservationName
      object:nil];

that's right since notifications are weak referenced you no longer need to remove yourself as an observer from them under garbage collection.


NSMapTable & NSHashTable
Under garbage collection all references to objects are considered to be strong by default. As a result of this you have to either explicitly make references weak by using __weak or by using a class specifically configured to use weak references. These classes include NSHashTable which is a class modeled after NSSet to support weak references, or NSMapTable which has been modeled after NSDictionary to support weak references.


Say goodbye to -dealloc, Say hello to -finalize
Under garbage collection the garbage collector will send the -finalize message to objects instead of -dealloc when collecting them. Most of the time this may not even be necessary to implement this as you will mainly just need -finalize for letting go of external resources like say closing files. In much the same way you'll call [super dealloc] at the end of -dealloc you will also need to call [super finalize] if you need to implement finalize. Additionally your finalize methods need to be thread-safe.
-(void)finalize
{
 if(myFileRef != NULL) {
  //close file
 }
 [super finalize]; 
} 
Making malloc'd memory collectable
There are times when you need to manually allocate memory through malloc or other such functions. Unfortunately the garbage collector does not automatically pick up on memory allocated like this. In order to remedy this Apple has provided the function NSAllocateCollectable().


Core Foundation & Garbage Collection
There are times when you need to dig down into Core Foundation to get functionality not found in the Cocoa Frameworks. As such Core Foundation will have to work with and interact with the garbage collector in gc apps. Luckly when allocating Core Founation objects when specifying the collector if you provide NULL, kCFAllocatorDefault or kCFAllocatorSystemDefault those all allocate memory from the garbage collection zone. In fact by default all Core Foundation Objects allocate from the garbage collection zone.

With Core Foundation any objects you allocate need to be either be released with CFRelease or CFMakeCollectable. Personally I use CFMakeCollectable as I think it makes the intent of the code more clear. Technically speaking CFRelease and CFMakeCollectable are nearly identical, if you do another CFRetain on a Core Foundation object you will need to use a CFRelease or CFMakeCollectable to balance it out. If you are writing code to run on both it'd be pretty easy to check for which one you need to do by checking to see if [NSGarbage collector defaultCollector] is NULL, otherwise CFMakeCollectable is just a no-op in a retain/release environment.
if ([NSGarbageCollector defaultCollector] == NULL) CFRelease(myCFString)


How do I turn this on in my projects?
Garbage Collection is currently only available on Mac OS X projects and not available on iOS yet. To turn on garbage collection in your application you need to open your project settings and search for garbage collection
gc_setting.png
There are 3 possible values you can have for your application.
(1) No GC Flag - Garbage Collection is not supported
(2) -fobjc-gc-only - When compiling with this set, Garbage Collection is required. If you have some bit of code in an external project that is gc only and try to use it in a project that does not support GC then you will get linker errors
(3) -fobjc-gc - When compiling with this both Garbage Collection code and traditional Retain/Release code is generated and the code can be loaded into any app. You probably will not compile apps with this setting and instead use this for Frameworks.
Typically you'll make your Apps support garbage collection or not, and your frameworks will be built with in supported mode (generating both gc and retain/release code.)


A note on Debugging GC
When using the heapshot in instruments you should set the environment variable AUTO_USE_TLC = NO because unfortunately the heapshot feature and the GC Thread Local collector don't work well together. Otherwise the heapshot feature in instruments will think you have more memory allocated than you really do. This and other GC environment variables are mentioned in the famous Mac OS X Debugging Magic Tech Note.
Instruments also contains a great instrument to show you when, for how long and how much the collector collected at various points in your application. If you are writing any gc code it would be to your advantage to run this every so often and get a feel for when the collector is running and what modes it is running in.
gc_modes.png

Conclusion

Managing memory in Objective-C is not nearly as hard as anybody would make it out to be. It's merely a matter of knowing the few memory management rules and periodically running Instruments on on your app, and the clang static analyzer in Xcode to eliminate memory issues. Garbage Collection eliminates many of the issues associated with manual objective-c retain/release, but you still have to know a few rules and how the collector works.

Releated Reading

Mac OS X Debugging Magic Tech Note
Memory Management Programming Guide
Garbage Collection Programming Guide
Instruments User Guide

 
...