FROM : Mike Abdullah
DATE : Mon Nov 19 22:52:37 2007
On 19 Nov 2007, at 21:42, Frank Reiff wrote:
> Hi everybody,
>
> During my latest hunt for irreproducible crashes, I've run into lots
> of thread-safety issues with a dialog that displays the progress of
> a worker thread.
>
> Cocoa bindings are not thread-safe, so you have to be extra careful
> about memory management, retain/release cycles and autorelease pools.
>
> I think I've pretty much fixed the problem, but now I'm in full
> paranoia mode and every single line of code looks like a potential
> crashing bug..
>
> From the worker thread I call the method updateStageText directly:
>
>
> - (void) updateStageText: (NSString*) text;{
>
> [self performSelectorOnMainThread:
> @selector(internalUpdateStageText:) withObject: text waitUntilDone:
> YES];
>
> }
>
> This calls a private method but on the main thread:
>
> - (void) internalUpdateStageText: (NSString*) text;{
>
> id old = paramStageText;
> [self willChangeValueForKey: @"stageText"];
> paramStageText = [text copy];
> [self didChangeValueForKey: @"stageText"];
> [old release];
> }
>
> All this is to make sure that KVC notifications go into the main
> thread and that the allocation itself is safe.
>
> As you notice, however, I call performSelectorOnMainThread with
> waitUntilDone: YES, which is extra safe but also extra slow.
>
> Now for the question: can I call it with waitUntilDone: NO !?
>
> The code as it stands wouldn't be thread safe because the NSString
> parameter might already have been de-allocated by the worker thread
> by the time [text copy] is executed on the main thread.
Using waitUntilDone:NO is perfectly acceptable. From the documentation:
The receiver and arg are retained until the perform is finished.
i.e. the "text" object will be retained by Cocoa for you.
>
>
> This could be solved by retaining the text parameter like this:
>
> - (void) updateStageText: (NSString*) text;{
>
> [text retain];
> [self performSelectorOnMainThread:
> @selector(internalUpdateStageText:) withObject: text waitUntilDone:
> YES];
> [text release];
> }
>
> Is this safe? I don't know whether the retain/release mechanism
> itself is thread-safe, but I presume it is.
>
> More worrying is the original
>
> [old release];
>
> line. This is perfectly fine if the Cocoa bindings NSTextField
> retains its value, but does it?
>
> I hope I’m only paranoid, but I would appreciate the insights from
> the Cocoa threading gurus :-)
>
> Best regards,
>
> Frank_______________________________________________
>
> Cocoa-dev mailing list (<email_removed>)
>
> 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/<email_removed>
>
> This email sent to <email_removed>
DATE : Mon Nov 19 22:52:37 2007
On 19 Nov 2007, at 21:42, Frank Reiff wrote:
> Hi everybody,
>
> During my latest hunt for irreproducible crashes, I've run into lots
> of thread-safety issues with a dialog that displays the progress of
> a worker thread.
>
> Cocoa bindings are not thread-safe, so you have to be extra careful
> about memory management, retain/release cycles and autorelease pools.
>
> I think I've pretty much fixed the problem, but now I'm in full
> paranoia mode and every single line of code looks like a potential
> crashing bug..
>
> From the worker thread I call the method updateStageText directly:
>
>
> - (void) updateStageText: (NSString*) text;{
>
> [self performSelectorOnMainThread:
> @selector(internalUpdateStageText:) withObject: text waitUntilDone:
> YES];
>
> }
>
> This calls a private method but on the main thread:
>
> - (void) internalUpdateStageText: (NSString*) text;{
>
> id old = paramStageText;
> [self willChangeValueForKey: @"stageText"];
> paramStageText = [text copy];
> [self didChangeValueForKey: @"stageText"];
> [old release];
> }
>
> All this is to make sure that KVC notifications go into the main
> thread and that the allocation itself is safe.
>
> As you notice, however, I call performSelectorOnMainThread with
> waitUntilDone: YES, which is extra safe but also extra slow.
>
> Now for the question: can I call it with waitUntilDone: NO !?
>
> The code as it stands wouldn't be thread safe because the NSString
> parameter might already have been de-allocated by the worker thread
> by the time [text copy] is executed on the main thread.
Using waitUntilDone:NO is perfectly acceptable. From the documentation:
The receiver and arg are retained until the perform is finished.
i.e. the "text" object will be retained by Cocoa for you.
>
>
> This could be solved by retaining the text parameter like this:
>
> - (void) updateStageText: (NSString*) text;{
>
> [text retain];
> [self performSelectorOnMainThread:
> @selector(internalUpdateStageText:) withObject: text waitUntilDone:
> YES];
> [text release];
> }
>
> Is this safe? I don't know whether the retain/release mechanism
> itself is thread-safe, but I presume it is.
>
> More worrying is the original
>
> [old release];
>
> line. This is perfectly fine if the Cocoa bindings NSTextField
> retains its value, but does it?
>
> I hope I’m only paranoid, but I would appreciate the insights from
> the Cocoa threading gurus :-)
>
> Best regards,
>
> Frank_______________________________________________
>
> Cocoa-dev mailing list (<email_removed>)
>
> 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/<email_removed>
>
> This email sent to <email_removed>
| Related mails | Author | Date |
|---|---|---|
| Frank Reiff | Nov 19, 22:42 | |
| Mike Abdullah | Nov 19, 22:52 | |
| Shawn Erickson | Nov 19, 22:58 |






Cocoa mail archive

