AFNetworking,UITableView和Blocks

End*_*ama 3 objective-c uitableview ios objective-c-blocks afnetworking

所以我正在阅读如何在实现API时避免在块中捕获自身?关于内存管理如何在完成块中引用self并且让我思考:以下内容是否会导致保留周期?

伪代码:

[AFnetworking requestGet:@"http://www.website.com" completionBlock:(^)(RequestObj* request, NSError* error){
      [self.tableView reloadData];
}];
Run Code Online (Sandbox Code Playgroud)

忽略语法问题,self.tableView会导致保留周期吗?是否有必要做以下事情?

__weak id weakSelf = self;
[AFnetworking requestGet:@"http://www.website.com" completionBlock:(^)(RequestObj* request, NSError* error){
      [weakSelf.tableView reloadData];
}];
Run Code Online (Sandbox Code Playgroud)

或者AFNetworking是否有某种记忆魔法可以阻止这种情况?


编辑Aaron Brager的礼貌

这里没有保留周期.但是如果你这样做了,在完成块中,你应该将weakSelf转换回一个强引用,这样它就不会在你的完成块中途被解除分配.

id strongSelf = weakSelf; 
[strongSelf.tableView reloadData];
Run Code Online (Sandbox Code Playgroud)

Hej*_*azi 6

当两个或多个对象彼此具有强引用时,会发生保留周期.

在这种情况下,块将具有强引用self,但self没有对块的强引用,所以你在这里很好,不需要使用 weakSelf.

当你有一个保留周期并且需要通过使用weakSelfis 来打破它的情况是当类具有对块的强引用时,如下例所示:

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
Run Code Online (Sandbox Code Playgroud)

在这个例子中,completionBlockself有对方强引用,所以你就会有一个保留周期在这里,需要打破它.

  • 请记住,强大的参考周期可能不是那么简单.例如,如果您的控制器具有对对象的强引用,该对象具有对完成块的强引用,然后完成块强烈引用您的控制器,您仍将具有保留周期,仅使用3个对象而不是2. (3认同)