您的位置:首页 > 理论基础 > 计算机网络

ios 关于使用异步网络请求时block回调的内存注意

2015-09-11 16:41 555 查看
在一个controller中,使用

NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

。。。。。。。。。

}];

网络方法请求网络内容,如果在block中,使用了self,或者仅仅使用了类的成员变量,那么这个controller对象就不会被释放!直到这个block的运行结束。这里需要另外特别强调的是,如果你在这个block中使用了nstimer中的scheduledTimerWithTimeInterval延时函数,那么延时调用的函数要负责处理self的引用,block的强引用不会在延时调用函数中继续起作用,比如下面的例子:

NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{

[NSTimer scheduledTimerWithTimeInterval:2.0 target:[UIApplication sharedApplication].delegate selector:@selector(test:) userInfo:self repeats:NO  ];
});

}];


当在test函数中调用传过去的self时,是没问题的,因为系统把userInfo这个函数做了强引用。

另外如果仅仅这样写,是不会调用timer的

NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(@"1111");

[NSTimer scheduledTimerWithTimeInterval:4.0 target:[UIApplication sharedApplication].delegate selector:@selector(test:) userInfo:self repeats:NO];
}];


因为这是个子线程,而它没有runloop run 进行消息循环,所以当函数结束,线程就结束,就没机会调用timer中的函数了。

也可以用下面这种技巧进行延时调用

NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(@"1111");
[NSTimer scheduledTimerWithTimeInterval:4.0 target:[UIApplication sharedApplication].delegate selector:@selector(test:) userInfo:self repeats:NO];
[[NSRunLoop currentRunLoop] run];

}];


由于这里的repeat是NO,这个timer结束后,整个runloop就没有事件源了,[[NSRunLoop currentRunLoop] run];函数就会立即返回,继续向下执行!

但是如果使用

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
UIView *view = self.view;
NSLog(@"view is %@",view);
});


这种block格式的调用就没事,因为又用到了block,而新的block又会保留self的强引用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: