EXC_BAD_ACCESS when using weakSelf in block / blocks

若如初见. 提交于 2020-01-04 05:25:41

问题


I have been struggeling with this issue for a while since i don't think i fully understand the retain cycles. I am totally new to this and i'm trying to learn more about it.

I am getting the EXC_BAD_ACCESS message with the following code.

I started using the weakSelf because i get 2 warnings about the retain cycle if i just use self.successBLock();. The exact warning is:

Capturing 'self' strongly in this block is likely to lead to a retain cycle

Maybe i shouldn't even bother using the weak but i am no so sure about this.

This is the part where i use the weakSelf in a block:

__weak Request *weakSelf = self;

[_operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    weakSelf.successBlock(operation.response, responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    weakSelf.failureBlock(operation.response, error);
}];

This is how i assign the block properties:

typedef void (^successBlock)(NSHTTPURLResponse *response, id responseObject);
typedef void (^failureBlock)(NSHTTPURLResponse *response, NSError *error);

@property (nonatomic, copy) successBlock successBlock;
@property (nonatomic, copy) failureBlock failureBlock;

回答1:


A __weak reference is set to nil if the object it points to is deallocated. So if your Request object has already been deallocated when the completion block is called, weakSelf is nil. In that case weakSelf.successBlock evaluates to a NULL pointer, and that is causing the crash.

The following pattern avoids this problem:

[_operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    Request *strongSelf = weakSelf;
    if (strongSelf) {
        strongSelf.successBlock(operation.response, responseObject);
    }
} ...

strongSelf will be nil if the Request object has already been deallocated. Otherwise the strong reference ensures that the object is not deallocated while the block is executing.

On the other hand, if you want the Request object to exist until the completion block is called, then you should not use a weak reference.




回答2:


When weakSelf is set to nil, weakSelf.successBlock is fine, but weakSelf.successBlock(operation.response, responseObject) will crash.



来源:https://stackoverflow.com/questions/16442476/exc-bad-access-when-using-weakself-in-block-blocks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!