所以我在读How do I avoid capturing self in blocks when implementing an API?关于在完成 block 中引用自身的内存管理如何工作,这让我开始思考:以下会导致保留周期吗?
伪代码:
[AFnetworking requestGet:@"http://www.website.com" completionBlock:(^)(RequestObj* request, NSError* error){
[self.tableView reloadData];
}];
忽略语法问题,self.tableView会导致retain cycle吗?是否有必要改为执行以下操作?
__weak id weakSelf = self;
[AFnetworking requestGet:@"http://www.website.com" completionBlock:(^)(RequestObj* request, NSError* error){
[weakSelf.tableView reloadData];
}];
或者 AFNetworking 是否有某种内存魔法来防止这种情况发生?
由 Aaron Brager 提供编辑
这里没有保留周期。但如果你这样做了,在完成 block 中,你应该将 weakSelf 转换回强引用,这样它就不会在你的完成 block 中途被释放。
id strongSelf = weakSelf;
[strongSelf.tableView reloadData];
最佳答案
当两个或多个对象彼此有强引用时,就会发生循环引用。
在这种情况下, block 将对 self
有一个强引用,但是 self
没有对 block 的强引用,所以 你是这里很好并且不需要使用 weakSelf
。
当你有一个保留循环并且需要使用 weakSelf
来打破它的情况是类对 block 有强引用,如下例所示:
typedef void (^CompletionCallback)(RequestObj* request, NSError* error);
@interface SomeClass() {
/// Strong reference to the block
CompletionCallback completionBlock;
}
@end
@implementation SomeClass()
- (void)someMethod {
completionBlock = ^(RequestObj* request, NSError* error) {
/// Strong reference to the class
[self.tableView reloadData];
};
[AFnetworking requestGet:@"http://www.website.com" completionBlock:completionBlock];
}
@end
在这个例子中,completionBlock
和 self
都有彼此的强引用,因此你在这里有一个保留循环,需要打破它。
关于ios - AFNetworking、UITableView 和 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19280650/