Reputation: 35933
I have an ivar like this declared on interface:
BOOL controllerOK;
I have to use this ivar inside a block that resides itself in a block. Something like
myBlockl = ^(){
[self presentViewController:controller
animated:YES
completion:^(){
if (controllerOK)
[self doStuff];
}];
};
If I try to do that, I see a warning:
capturing self strongly in this block is likely to lead to a retain cycle
for the if (controllerOK) line.
This does not appear to be one of those blocks problems that you create another variable using __unsafe_unretained before the block starts. First because this instruction cannot be used with a BOOL and second because the ivar controllerOK has to be tested on runtime inside the block. Another problem is that the block itself is declared on the interface, so it will be used outside the context where it is being created.
How do I solve that?
Upvotes: 2
Views: 385
Reputation: 17500
controllerOK
implicitly compiles as self->controllerOK
because it needs to access its memory location through self
. Because of that, it is "one of those blocks problems", although in this case just a simple BOOL
variable will do.
__weak typeof(self) weakSelf = self;
myBlockl = ^(){
BOOL isControllerOK = controllerOK;
[self presentViewController:controller animated:YES completion:^(){
if (isControllerOK)
{
[weakSelf doStuff];
}
}];
};
I put _weak
there because even if you fix the warning message for controllerOK
, you'll get it again in [self doStuff]
Upvotes: 1
Reputation: 318774
This should work:
__weak id this = self;
myBlockl = ^(){
[self presentViewController:controller
animated:YES
completion:^(){
if (this->controllerOK)
[this doStuff];
}];
};
Upvotes: 2
Reputation: 437381
You need to replace references to your objects with weak
references.
The typical fix is to declare a local variable:
__weak id weakSelf = self;
As rmaddy's observed, referring to an ivar, controllerOK
, also generates a strong reference cycle. You can replace BOOL controllerOK
ivar with an object:
NSNumber *controllerOK;
and then you can use a weak
reference to that, such as in the following:
controllerOK = @YES;
__weak typeof(self) weakSelf = self;
__weak NSNumber *weakControllerOk = controllerOK;
myBlockl = ^(){
[weakSelf presentViewController:controller
animated:YES
completion:^(){
if ([weakControllerOk boolValue])
[weakSelf doStuff];
}];
};
Upvotes: 0
Reputation: 35933
unfortunately the only solution that worked was to convert BOOL controllerOK to a property nonatomic, assign and then use it inside the block.
I have tested all solutions you have posted here, without success.
Upvotes: -1
Reputation: 534895
The problem may be that you are not in fact quoting your actual code. I tried your code and it compiled under ARC with no warning. But I had to modify it a little because your syntax for declaring a block is wrong. Thus you clearly did not copy and paste your actual code. It is a waste of time for people to try to help you if you don't show the real code that is giving trouble.
Upvotes: 0
Reputation: 183
can you try like this
myBlockl = ^(){
[self presentViewController:controller
animated:YES
completion:^(BOOL isFinished){
if (isFinished == controllerOK)
[self doStuff];
}];
};
I am not very familiar about blocks but it worked for me.....
Upvotes: -1