On 10/10/2009, at 12:29 PM, Jens Alfke wrote:


On Oct 8, 2009, at 7:33 PM, Glen Low wrote:

1. The code is not GC friendly as between the end of start and the beginning of finishWithSomething, there are no references to the object, so it may be collected.

There must be references to it; otherwise how would that object's methods get called later on? Either it's a delegate of another object (an NSURLConnection or NSTimer or whatever) or it starts a new thread to run one of its methods. Either way, there are references to the object that keep it alive.

2. The static analyzer in Xcode 3.2 doesn't like the construction, thinking that the object is leaking from the start method.

I'm not sure what to do about that. Casting the result to (void) might help, to explicitly state that you don't want to use the result. (Does the static analyzer even work with GC? Stating that the object is "leaking" only makes sense in a ref-counted environment.)

It occurs to me that if I try to simulate the usual design pattern of NSAlert, NSThread etc. callbacks that will keep the static analyzer happy and probably be safer in the long run i.e.

- (void)start
{
        Something* something = [[Something alloc] initWithDelegate:self];
        [something doSomething];
        [something release];    // #3
}

- (void)finishWithSomething:(Something*)something
{
        [something release];
}

Note that the finishWithSomething: callback can happen after start has finished.

So if Something uses e.g. an NSAlert

- (id)initWithDelegate:(id)delegate
{
        if (self = [super init])
        {
                _alert = [[NSAlert alloc] init];
                _alert.delegate = self;
                _delegate = delegate;
        }
        return self;
}

- (void)doSomething
{
        [self retain];  // #1
[_alert beginSheetModalForWindow:xxx modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:NULL];
}

- (void)alertDidEnd:(NSAlert*)alert returnCode:(int)returnCode contextInfo:(void*)contextInfo
{
        [_delegate finishWithSomething:self];
        [self release]; // #2
}

Qn:

1. Are #1 and #2 strictly necessary? At the point of #1, the retain count of something is just 1, since the alert doesn't retain its delegate, and the release at #3 would have caused the object to be dealloc'ed. Then the alert will end up messaging a zombie. Therefore we need to add an extra retain and release around the callback.

2. In the presence of GC, #1 and #2 are no-ops. Does calling beginSheetModalForWindow: with modalDelegate == self sufficient to keep a reference alive to the something object? Or should I use CFRetain and CFRelease instead (are the effects different here from - retain and -release)?




Cheers, Glen Low


---
pixelglow software | simply brilliant stuff
www.pixelglow.com
aim: pixglen
twitter: pixelglow

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to