问题
I have this problem: a block inside a block.
self.createStuff = ^ (NSString *text) {
self.post.onCompletion = ^(NSURLResponse *response, NSData *data, NSError *error){
[self doStuff]; // error here
};
[self doMoreStuff]; // error here
};
I will have errors in [self doStuff] and on [self doMoreStuff]. The error is capturing 'self' strongly in this block is likely to lead to a retain cycle
Easy you say, just add
id mySelf = self;
before the first block and use mySelf instead.
Nope. This will not save my problem, simply because mySelf being of kind id will not give me a post property, needed by the second line. So I need to declare it like
MyClass *mySelf = self;
Making it like:
MyClass *mySelf = self;
self.createStuff = ^ (NSString *text) {
mySelf.post.onCompletion = ^(NSURLResponse *response, NSData *data, NSError *error){
[self doStuff]; // error here
};
[mySelf doMoreStuff];
};
OK, you say, now the self.post.onCompletion line and doMoreStuff are not complaining anymore, but we have another self inside onCompletion... because this is a block inside a block. I can repeat the process creating another weak reference like and this will have to be a weak reference to a weak reference
MyClass *internalMyself = mySelf;
and use
[internalMyself doStuff];
this seems to me to be a pretty pathetic way to do this and more, the app hangs when this method runs. Something like the reference is being deallocated before the method executes...
How do I solve this charade?
thanks.
note: this is being compiled to iOS 6+
回答1:
You're pretty close. Just replace your solution
MyClass *mySelf = self;
self.createStuff = ^ (NSString *text) {
mySelf.post.onCompletion = ^(NSURLResponse *response, NSData *data, NSError *error) {
[self doStuff]; // error here
};
[mySelf doMoreStuff];
};
with
__weak MyClass *mySelf = self;
self.createStuff = ^ (NSString *text) {
mySelf.post.onCompletion = ^(NSURLResponse *response, NSData *data, NSError *error) {
[self doStuff]; // error here
};
[mySelf doMoreStuff];
};
The problem with the first solution is that mySelf
isn't designated weak
, so it's ownership qualifier is implicitly __strong
(see LLVM's documentation). I'm not sure why this quiets the warning in the first block, but designating the reference __weak
will fully remove the retain cycle.
来源:https://stackoverflow.com/questions/14667610/arc-capturing-self-block-inside-a-block-and-reference-being-released-before-e