Mailing Lists: Apple Mailing Lists
Image of Mac OS face in stamp
__block qualified ObjC object variables not retained by referencing ^{} block?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

__block qualified ObjC object variables not retained by referencing ^{} block?



I started to dig in to the new blocks feature and this line from Blocks Programming Topics ( http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Blocks/Articles/bxVariables.html#//apple_ref/doc/uid/TP40007502-CH6-SW4 ) caught my eye:

1) In a reference-counted environment, by default when you reference an Objective-C object within a block, it is retained.
2) This is true even if you simply reference an instance variable of the object.
3) Object variables marked with the __block storage type modifier, however, are not retained.

My question is: what is the logic behind #3?  After some testing, I've come to the conclusion that use of __block qualified ObjC object variables can't be used within a ^{} block if that blocks lifetime is going to extend past the lifetime of what ever created the ^{} block.  For example:

typedef void(^SimpleBlock)(void);

SimpleBlock makeBlock(int intArg) {
  __block int cnt = 0;
  __block NSMutableString *string = [NSMutableString stringWithFormat:@"A mutable string! %d", intArg++];
  // [string retain]; // <-- If the runtime will not automatically retain 'string', we have to... ?
  SimpleBlock retBlock = ^{ NSLog(@"Hello, from the world of blocks"); NSLog(@"Goodbye from the world of blocks! cnt: %d, intArg: %d, string: '%@'\n", ++cnt, intArg, string); };
  retBlock = [[retBlock copy] autorelease]; // copy + autorelease on its own line for clarity.
  return(retBlock);
}

In the above example, the __block qualified variable 'string' is /not/ automatically retained by 'retBlock'.  This means as soon as the autorelease pool that 'string' was created in pops, it will -dealloc string.  After that point, invoking the block via 'retBlock()' will likely result in a crash.

So, there's a bit of a problem here..  If you try to compensate by -retain'ing 'string', there's no way to -release it when the block gets -dealloc'd, and you leak 'string'.  In a nut-shell, I can't figure out how to get __block qualified ObjC object variables to "work", except for trivial, toy examples.

The only thing that I can think of is this design decision was made because there was a fear that people were going to "screw up" reference counted memory management for __block qualified objects.  That seems pretty weak, especially considering that the alternative that was chosen has the effect of making __block qualified ObjC object variables useless if you need the ^{} block to live past the point in which you created the ^{} block.
 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Objc-language mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2011 Apple Inc. All rights reserved.