Objective C chaining calls
cocoa, objective-c
Solution
You probably want to make `myCoolDelegate` an instance variable, `static` variable, or create it in a xib file (like the Xcode template you get from File > New Project… > Cocoa Application does).
Actually, both examples are technically wrong. One "accidentally works" because the compiler isn't (currently!) performing the legal optimization to release `myCoolDelegate` as soon as it's used for the last time, which is before the `NSApplicationMain` call.
Per the spec, "By default, local variables of automatic storage duration do not have precise lifetime semantics. Such objects are simply strong references which hold values of retainable object pointer type, and these values are still fully subject to the optimizations on values under local control."
Usually `-setDelegate:` methods don't retain/strongly-reference things, to prevent strong reference cycles, where two objects both keep each other from being deallocated. For compatibility, `NSApplication` uses an `__unsafe_unretained` reference to it's `delegate` instead of a (usually preferable) `__weak` reference (this might change in future OS X versions course). So when `NSApplication` tries to talk to it's `delegate` after it has been deallocated, you get a crash. The `delegate` can be deallocated here because nothing is strongly referencing it after the `-setDelegate:` call.
In summary: using an implicit temporary variable, or an explicit local variable only keep an object alive until the variable's last use. They do not guarantee that the object is kept alive as long as the variable is in scope. It's unfortunate that the compiler isn't being as aggressive as it could be, which makes an explicit local variable appear to extend an object's life time more than it's guaranteed to. You might see different behavior if you turned on more optimizations. You need to make `myCoolDelegate` a "longer lived" kind of variable (ivar, `staic`, or global) or use the `objc_precise_lifetime` attribute when declaring it.
__attribute__((objc_precise_lifetime)) MyCoolDelegate* myCoolDelegate = [[MyCoolDelegate alloc] init];
This situation is complicated, but it doesn't come up in practice much, because things that are delegates of another object are almost always referenced through an ivar, or something "long lived", not just a local variable.
Problem
I'm new to Objective C so please forgive me if this question seems stupid. First sample: ``` int main(int argc, const char* argv[]) { @autoreleasepool { MyCoolDelegate* myCoolDelegate = [[MyCoolDelegate alloc] init]; [[NSApplication sharedApplication] setDelegate: myCoolDelegate]; return NSApplicationMain(argc, argv); } } ``` Second sample: ``` int main(int argc, const char* argv[]) { @autoreleasepool { [[NSApplication sharedApplication] setDelegate: [[MyCoolDelegate alloc] init]]; return NSApplicationMain(argc, argv); } } ``` As C++ programmer I expect both main functions should have the same behaviour, but second main crashes on `return NSApplicationMain(argc, argv);` while first one sets the delegate and works as expected. Can you please explain what is the difference between these samples? Is there some black magic around temporary objects in Objective C(I assume `[MyCoolDelegate alloc] init]` will return a temporary object of type `MyCoolDelegate`)?