Skip to content

Instantly share code, notes, and snippets.

@iamleeg
Last active December 31, 2015 00:59
Show Gist options
  • Save iamleeg/7911006 to your computer and use it in GitHub Desktop.
Save iamleeg/7911006 to your computer and use it in GitHub Desktop.
Does this actually have a retain cycle?
#import <Foundation/Foundation.h>
@interface A : NSObject
- (void)doThingWithObject:(id)o completion:(void(^)(void))completionHandler;
@end
@implementation A
- (void)doThingWithObject:(id)o completion:(void(^)(void))completionHandler
{
NSLog(@"object: %@", o);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if(completionHandler) completionHandler();
});
}
@end
int main(int argc, char *argv[]) {
@autoreleasepool {
A *a = [A new];
NSArray *someThings = @[@0, @1, @2];
NSEnumerator *e = [someThings objectEnumerator];
__block void(^ completionHandler)(void);
completionHandler = ^{
id o = [e nextObject];
if (o) {
[a doThingWithObject:o completion:completionHandler];
}
};
completionHandler = [completionHandler copy];
completionHandler();
sleep(1);
}
}
@iamleeg
Copy link
Author

iamleeg commented Dec 11, 2013

See https://gist.github.com/iamleeg/7911205 which no longer has the warning. I think it doesn't have a retain cycle either, but now I'm unsure. :-S

@mattjgalloway
Copy link

There's no leak, but only because we know that nextObject will at some point return nil. The compiler doesn't know that, so it warns. I guess even if nextObject never returned nil there wouldn't be a "leak" because the block would continually be doing something. It depends on your definition of leak really :-).

To me, this kind of logic is a smell anyway and the warning is useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment