On 21 Nov 2012, at 10:56, Andreas Grosam <agro...@onlinehome.de> wrote:
> I've defined a class Foo that defines a block via a property: > > @property (copy) void (^progressHandler)(RXProgressState progressState, > NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite); > > The property is synthesized by the compiler, ARC enabled. > > The block is usually invoked on a private thread for several times until an > action finishes (an asynchronous NSURLConnection). > A client of class Foo should be able to set the block property at any time > from any thread - that is it should also be able to set the block to NULL. > Now, I'm worried about thread safety. > > First, is it a good measurement to use a property with the "atomic" attribute? Not really, as your block may be released (by the setter) between getting the block and invoking it. > Secondly, I'm invoking the block as follows (from within a > NSURLConnectionDelegate method): > > progress_handler_block_t block; > if ( (block=self.progressHandler) != NULL) { > block(RXProgressStateStart, 0, self.source.size); > } > > > since it appears to me, that > > if (_progressHandler) { > _progressHandler(RXProgressStateStart, 0, self.source.size); > } > > or > > if (self.progressHandler) { > self.progressHandler(RXProgressStateStart, 0, self.source.size); > } > > isn't thread safe. > > > Your comments are welcome! Grand Central Dispatch is your friend. @implementation MyClass static dispatch_once_t onceToken; static dispatch_queue_t dispatchQueue; typedef (void(^ProgressHandler)(RXProgressState progressState, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite); - (void)setProgressHandler:(ProgressHandler)progressHandler { dispatch_once(&onceToken, ^ { dispatchQueue = dispatch_queue_create("RXProgressQueue", DISPATCH_QUEUE_SERIAL); }); dispatch_sync(dispatchQueue, ^() { if (_progressHandler != progressHandler) { [_progressHandler release]; _progressHandler = [progressHandler copy]; } }); } - (void)progressHandler { return _progressHandler; } - (void)callSite { … dispatch_once(&onceToken, ^ { dispatchQueue = dispatch_queue_create("RXProgressQueue", DISPATCH_QUEUE_SERIAL); }); dispatch_sync(dispatchQueue, ^() { ProgressHandler handler = [self progressHandler]; handler(…); }); … } Tom Davie _______________________________________________ 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: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com