Aug 03

One interesting thing to note about IBOutlet and their connection to Interface Builder. If the field being defined as an IBOutlet does not have an explicit “setting” method, either by manually writing it or by using @property and @synthesize, the route to connect the Nib’s definition to this field in the file is setValue:forKey. This method retains the field that is set as an outlet. Therefore, even though you didn’t retain the field anywhere in your code, you need to release it in your dealloc method.

So, I typically just make sure all outlets are properties.

Tagged with:
Jul 29

Ok, this is easily my favorite feature of the Objective-C language thus far. That is Categories. Categories allows you to modify an existing class “in place”, without having to subclass. In many cases it doesn’t make sense to extend another class if you only wish to add functionality (but add no properties). Also, creating a Category does not require you to add to the inheritance chain which can be problematic if the class you are extending is not under your control.

For our example, I want to add functionality to NSString (a core foundation class). I’ll add a single Class Method that takes any string and presents it as if I’ve said it.

@interface NSString (MarksString)
+ (NSString *) markifyString:(NSString*)string;
@end

When writing the interface, you use the class you are extending (NSString) and define the category (MarksString). You can then add any additional interface elements here.

The implementation is just as expected:

@implementation NSString (MarkString)

   + (NSString *) markifyString:(NSString *) string {
      return [NSString stringWithFormat:@"Mark says \"%@\"", string];
   }
@end

To use this new category, all you have to do is #import the new category, which will add the functionality to NSString at run time.

NSString * original = @"Life is like a box of chocolate";
 NSLog([NSString markifyString:original]);

Displays:

2009-07-29 17:28:58.726 WhatATool[16449:10b] Mark says "Life is like a box of chocolate"
Tagged with:
Jul 29

Archiving complex data types can be a bit of a chore, managing object relationships, etc. However, Objective-C provides a fantastic mechanism through the NSCoding protocol. This protocol provides two methods: encodeWithCoder: and initWithCoder:. Implementing these methods is actually quite easy, simply use the provided NSCoder object and encode the data you are responsible for. If your data is primitive types, or Foundation objects you are done. If you manage another custom class, that class also needs to conform to the NSCoding protocol as well and implement the encodeWithCoder: and initWithCoder: methods.

This is a very natural way of managing Archiving as each object as it keeps it within the domain of the object itself and is maintainable. In fact, when we decided the Java Serialization was unacceptable for our needs at NCsoft and jMonkey Engine we wrote our own serialization scheme that was almost identical to this method.

@interface PolygonShape : NSObject <NSCoding> {
    int numberOfSides;
    int minimumNumberOfSides;
    int maximumNumberOfSides;
    Location *location;
}

- (void) encodeWithCoder: (NSCoder *) encoder {
    [encoder encodeInt:numberOfSides forKey:@"PolygonShapeNumberOfSides"];
    [encoder encodeInt:minimumNumberOfSides forKey:@"PolygonShapeMinimumNumberOfSides"];
    [encoder encodeInt:maximumNumberOfSides forKey:@"PolygonShapeMaximumNumberOfSides"];
    [encoder encodeObject:location forKey:@"PolygonShapeLocation"];
}

- (id) initWithCoder: (NSCoder *) decoder {
    numberOfSides = [decoder decodeIntForKey:@"PolygonShapeNumberOfSides"];
    minimumNumberOfSides = [decoder decodeIntForKey:@"PolygonShapeMinimumNumberOfSides"];
    maximumNumberOfSides = [decoder decodeIntForKey:@"PolygonShapeMaximumNumberOfSides"];
    location = [[decoder decodeObjectForKey:@"PolygonShapeLocation"] retain];

    return self;
}

@interface Location : NSObject <NSCoding> {
    int x;
    int y;
}

- (void) encodeWithCoder: (NSCoder *) encoder {
    [encoder encodeInt:x forKey:@"LocationX"];
    [encoder encodeInt:y forKey:@"LocationY"];
}

- (id) initWithCoder:(NSCoder *) decoder {
    x = [decoder decodeIntForKey:@"LocationX"];
    y = [decoder decodeIntForKey:@"LocationY"];

    return self;
}

if ([NSKeyedArchiver archiveRootObject:shape toFile:@"store.arch"] == NO ) {
    NSLog(@"Failed to archive");
}

PolygonShape *shape = [NSKeyedUnarchiver unarchiveObjectWithFile:@"store.arch"];
Tagged with:
Jul 29

When retaining an object it is important to know the relationship of that object to the object retaining it. If you are not careful, you can enter a retain cycle, that will not allow an object to be deallocated. Matt Gallagher at Cocoa With Love has a great article on Retain Cycles and how to avoid them. He gives 5 simple rules to avoid this situation:

  1. An Object Must never retain its parent – If a Parent Object is composed of a Child Object where the dealloc method releases the Child Object, the Child Object must not retain the Parent. Otherwise, the retain count of the Parent will never reach 0 and, thus, its dealloc will never be called releasing the Child Object.
  2. No Hierarchical Ancestor May be Retained – Know the ownership chain of your objects. Period.
  3. “Connection” Objects Should Not Retain Their Target – Buttons should never retain the Controller, for example.
  4. Use “Close” methods to Break Cycles – If there exists a retain cycle, write a custom method to clean up. This basically takes over for the dealloc method that you can manually execute.
  5. Temporary “retains” Must be Temporary – If you break any of the rules (which you will), do it temporarily and make sure it’s temporary.

The article is quite interesting and enlightening for how retain relationships are established.

Tagged with:
Jul 27

Objective-C supports two directives: Compiler and Preprocessor. Compiler directives are prepended by ‘@’ while preprocessor ‘#’. I’ve been exposed to ‘#’ for awhile with C/C++, with ‘@’ being new with Objective-C. One interesting Compiler Directive is @class. This is actually similar to the #import, but with one big advantage.

Imagine that there is a class Shape that contains a position defined by a Location object. Shape never does anything with this Location except provide accessors, it never calls any of Location’s methods, etc. You can express this as below:

#import "Location.h"

@interface Shape : NSObject {
 Location *center;
}

@property *Location center;

However, because we are never actually “using” the Location object, we can be more efficient:

@class Location;
@interface Shape : NSObject {
 Location *center;
}

@property *Location center;

This tells the Compiler that we don’t need to know about its definition (and thus, don’t need to process the entire .h file) as we are not using it. @class gives the Compiler just enough information to compile, and allow “Shape” to contain the object.

Tagged with:
Jul 22

The @optional tag in a protocol will define methods that can optionally be implemented. It is important when using a protocol (as a delegate or similar) to check that the implementing protocol has implemented the optional method before messaging it (using respondsToSelector:).

@protocol MyProtocol
@optional
// implementation of these methods is optional
- (void)anOptionalMethod;
@required
// implementation of this method is required
- (void)aRequiredMethod;
@end

Before using it you would do the following:

if ([delegate instancesRespondToSelector:@selector(aMethod)]) {
[delegate aMethod];
}
Tagged with:
Jul 21

Most Object Oriented programmers cling to the Encapsulation element of the three core of Object Oriented programming more than any other. And with most languages this means you spend a lot of your time as a programmer writing getter and setter methods. With the advent of many IDE features, you can have the code generated for you, but it is still code living in your source.

Objective C provides a mechanism to ease the developer from this burden. A “property” provides shorthand to generate accessor methods at compile time.

@property (<attributes>) <type> <name>

In the implementation, you can tell it to generate the accessors using “synthesize”

@synthesize <name>

So, if we have an int X, and I really don’t feel like writing the accessor methods, my code would look like the following:

@interface MyClass : NSObject {

int x;

}

@property(readwrite) int x;

@end

@implementation MyClass

@synthesize x;

@end

This will create methods: [MyClass x] and [MyClass setX:intValue]

Tagged with:
Jul 11

I have been trying to be a good code citizen and make sure all data I create is released and I don’t cause any memory leaks. I found that I was doing a lot of the following:

NSLog([NSString stringWithFormat:@"Class Name: %@", [object class]]);

Therefore, I didn’t have a reference to the object that I created, and couldn’t explicitly release it. This sort of code convention is just from my Java background, and the fact that I’m used to local method variables to be created on the stack. Since, Obj-C likes to create objects on the heap, you can’t rely on anything going out of scope and getting chewed up (doesn’t have Garbage Collection (at least in the iPhone API)).

After debating it a bit, I learned that “stringWithFormat” returns an NSString that is set to autorelease. That’s great, takes care of my problem. When the event handling loop completes all the string will be released, and all is well. But, there is still one thing bothering me. Here is the documentation for “stringWithFormat”:

XcodeScreenSnapz006

Nowhere does it say the returned string is set to be autoreleased.

In, Session 3 of the Stanford Lectures, Evan Doll states that Method names give you the answer:

Method Names & Autorelease
•Methods whose names includes alloc or copy return a retained object that the caller needs to release
•All other methods return autoreleased objects
•This is a convention- follow it in methods you define!

NSMutableString *string = [[NSMutableString alloc] init];  // We are responsible for calling -release or -autorelease
[string autorelease];
NSMutableString *string = [NSMutableString string];
// The method name doesn’t indicate that we need to release it
// So don’t- we’re cool!

So, there’s the answer. Based on the name of the method, I should know if that object is set to be autoreleased or not. But doesn’t this strike anyone as particularly dangerous? As a developer I am at the mercy of a 3rd Party API developer to follow convention properly. In my mind, this should be documented and done so using any auto-documentation facilities that Xcode has (don’t actually know if it has any).

Tagged with:
Jul 09

What would happen with the following code?

MyObject* myObj = [[MyObject alloc] init];

[myObj release];

[myObj method];

Hopefully, if you are lucky, your program will crash. But, it may not, nothing might happen. It may not crash immediately, but only have some other application writes to that memory location.

Therefore, it is typically considered good practice to set myObj to “nil”. This is because, calling a message on “nil” does nothing.

Also, this is safe to do in the scope of your application. Setting an object reference to nil only affects your local scope (essentially zeroing out the pointer), so if that object was retained elsewhere, calling nil will not affect it.

Tagged with:
Jul 09

Objective-C’s memory management uses allocation of memory and deallocation, similar to C’s malloc/free mechanism. Objective-C makes use of alloc/dealloc. However, it is more complex than that. Every NSObject has a “retain” count. Where alloc’ing sets the retain count to 1 for that object. What is interesting, is as a user you should never call “dealloc” directly. This is because Objective C will dealloc the object automatically when it’s retain count reaches 0. How would a retain count reach 0? When you are done with the object, you should call “release”.

This also means that if you are working on an instance of an object, you are responsible for managing its memory. I.e. you never know when that instance that was passed to you will have release called on it, causing your copy to be a invalid reference. So, if you have a method that takes an object and uses it for awhile (setting it to an instance variable, for example), you should retain it, and release it when you are finished.

You’ll see this paradigm used throughout the UI Toolkit. For example,

MyView *view = [[MyView alloc] initWithFrame:[window frame]];
[window addSubview:view];
[view release];

You’ll notice that as a client, I create a view and add it to a window view. That is the extent of what I need it for, so, therefore, release it. If the window’s addSubview method did not retain it, that view would be destroyed. Therefore, reading the documentation of NSView, you can see:

addSubview:
Adds a view to the receiver’s subviews so it’s displayed above its siblings.

- (void)addSubview:(NSView *)aView

Parameters
aView
The view to add to the receiver as a subview.

Discussion
This method also sets the receiver as the next responder of aView.

The receiver retains aView. If you use removeFromSuperview to remove aView from the view hierarchy, aView is released. If you want to keep using aView after removing it from the view hierarchy (if, for example, you are swapping through a number of views), you must retain it before invoking removeFromSuperview.

Emphasis is mine, but you’ll see that it is retained.

Tagged with:
preload preload preload