Cocoa Programming for Mac OS X - Aaron Hillegass [31]
When would you want to use a weak pointer? Recall the retain-cycle issue we touched on before, where two objects are retaining each other and thus are never deallocated. In ARC, this is referred to as a strong reference cycle. By using weak references strategically, we can avoid these cycles altogether. Consider the following class definition:
@interface Person : NSObject {
Person *parent; // Bad! This causes a strong reference cycle!
NSMutableArray *children;
}
@end
Because references are strong by default, a class like this would quickly result in a strong reference cycle. Person has a strong reference to both parent and children; the children array has strong references to objects it contains. We can use the __weak qualifier to fix this problem and make parent a weak reference:
@interface Person : NSObject {
__weak Person *parent; // Good! No strong reference cycle.
NSMutableArray *children;
}
@end
This pattern is commonly used in Objective-C: The parent-to-child relationship is strong, whereas the child-to-parent relationship is weak.
Note that only classes compiled with ARC can have weak references made to them. An exception will be thrown if you try to make an assignment to a __weak variable and the class does not support weak references. You can use the __unsafe_unretained qualifier in place of __weak in cases like this. The object will not be retained, but this reference will not be set to nil when the object is deallocated.
ARC Odds and Ends
• ARC code is able to work with manually reference-counted code without modification. In fact, it is possible to use ARC on a per file basis. It is important, however, that manually reference-counted code adhere to the rules discussed earlier in this chapter.
• Xcode provides a migration tool to convert existing projects to ARC. This tool can be found in the Edit menu, under Refactor -> Convert to Objective-C Automatic Reference Counting.
• Although ARC code can run on Mac OS X 10.6 and iOS 4, weak references are not supported on those platforms.
• Although Objective-C can be intermixed with plain C in most cases, ARC does not allow C structures to contain object pointers.
• Property names may not begin with new.
• Under ARC it is an error to call retain, release, autorelease, or dealloc (such as with [super dealloc]). Additionally, you cannot override retain, release, or autorelease.
Chapter 5. Target/Action
Once upon a time, there was a company called Taligent. Taligent was created by IBM and Apple to develop a set of tools and libraries like Cocoa. About the time Taligent reached the peak of its mindshare, Aaron met one of its engineers at a trade show and asked him to create a simple application: A window would appear with a button, and when the button was clicked, the words “Hello, World!” would appear in a text field. The engineer created a project and started subclassing madly, subclassing the window and the button and the event handler. Then he started generating code: dozens of lines to get the button and the text field onto the window. After 45 minutes, Aaron had to leave. The app still did not work. That day, Aaron knew that the company was doomed. A couple of years later, Taligent quietly closed its doors forever.
Most C++ and Java tools work on the same principles as the Taligent tools. The developer subclasses many of the standard classes and generates many lines of code to get controls to appear on windows. Most of these tools work.
While writing an application that uses the AppKit framework, you will seldom subclass the classes that represent windows, buttons, or events. Instead, you will create objects