Reputation: 2702
One of my methods (mySecondMethod) receives a block and need to add an additional treatment to this block before passing it as an argument to another method. Here is the code sample:
- (void)myFirstMethod {
// some code
__weak MyController *weakSelf = self;
[self mySecondMethod:^(BOOL finished) {
[weakSelf doSomething:weakSelf.model.example];
}];
}
- (void)mySecondMethod:(void(^)(BOOL finished))completion {
void (^modifiedCompletion)(BOOL) = ^void(BOOL finished){
completion(finished);
_messageView.hidden = YES; //my new line
};
[UIView animateWithDuration:duration animations:^{
//my code
} completion:modifiedCompletion];
}
When run, I got a bad access error on completion(finished)
line. completion
is NULL. I tried to copy the block like this:
void (^copiedCompletion)(BOOL) = [completion copy];
void (^modifiedCompletion)(BOOL) = ^void(BOOL finished){
copiedCompletion(finished);
_messageView.hidden = YES; // my new line
};
but still got the error.
When I empty out completion block, the crash still happen so the crash is not due to what is inside.
Any idea how to solve this? Thanks!
Upvotes: 1
Views: 2745
Reputation: 2819
I think you are getting the bad access because of this
// some code
__weak MyController *weakSelf = self;
[self mySecondMethod:^(BOOL finished) {
[weakSelf doSomtehing:weakSelf.model.example];
}];
Try changing it to.
id example = self.model.example;
[self mySecondMethod:^(BOOL finished) {
[self doSomething:example];
}];
Edit
The block needs to be copied before being called.
Side Note
Do a check before calling blocks to avoid unexpected crashes.
if (completion) {
completion(finished);
}
Upvotes: 1