第3月第9天 循环引用 block

一.一个对象没有被引用,那么在函数块完成时就会被dealloc,这种情况因为对象销毁了,block块也永远不会执行。

    MyNetworkOperation *op = [[MyNetworkOperation alloc] init];

    [op addCompletionHandler:^(MyNetworkOperation *completedOperation) {
completion([NSArray array]); } errorHandler:^(MyNetworkOperation *completedOperation, NSError *error) {
errorBlock(completedOperation, error);
}];

二. NSOperationQueue引用

1.NSOperationQueue可以addOperation,这样operation对象就会被引用了,并在operation完成时operation对象会dealloc。

    MKNetworkOperation *op = [self operationWithPath:OralThingCommentsByThing36idPage(thing36id,page)
params:nil
httpMethod:GETMETHOD];
[self addSwycHeaders:op];
[op addCompletionHandler:^(MKNetworkOperation *completedOperation) { NSString *valueString = [completedOperation responseString];
DLog(@"�� serverResponse:%@��", valueString); completion([NSArray array]); } errorHandler:^(MKNetworkOperation *completedOperation, NSError *error) {
errorBlock(error);
}]; [self enqueueOperation:op];
return op;

2.但如果uiviewcontroller又引用了operation,block块中又调用了self,那么就有循环引用了,解决方法是weakSelf.

    MKNetworkOperation *thingsOp = [[SwycEngine sharedEngine] OralThingCommentsByThing36id:thing36id page:page rows:rows CompletionHandler:^(id object) {
NSArray *arr = object; self.totalThingComments = [Application sharedInstance].totalThingComments; if (refresh) {
self.page = ;
vc.thingComments = [NSMutableArray arrayWithArray:arr];
} else {
if (arr.count > ) {
self.page++;
[vc.thingComments addObjectsFromArray:arr]; }
}
[vc.tableView reloadData];
// 结束刷新
[self.tableView.mj_footer endRefreshing];
[self.tableView.mj_header endRefreshing];
} errorHandler:^(NSError *error) {
// 结束刷新
[self.tableView.mj_footer endRefreshing];
[self.tableView.mj_header endRefreshing]; }];
self.thingsOp = thingsOp;

三、数组应用

一个其他对象的数组可以addObject,这样对象就会被引用了,但block完成时数组还在,所以对象没有dealloc。解决方法是数组移除对象。

1.其他操作移除

    MyNetworkOperation *op = [[MyNetworkOperation alloc] init];

    [op addCompletionHandler:^(MyNetworkOperation *completedOperation) {
completion([NSArray array]); } errorHandler:^(MyNetworkOperation *completedOperation, NSError *error) {
errorBlock(completedOperation, error);
}]; [self.operationArr addObject:op]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)( * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.operationArr = nil;
}); return op;

2.以下代码好像会循环引用,self.operationArr包含op,op的block里又调用self,实际是对象会被dealloc.

    __weak typeof(op) weakOp = op;

    [op addCompletionHandler:^(MyNetworkOperation *completedOperation) {
completion([NSArray array]); self.operationArr = [NSMutableArray array];
if (weakOp) { } } errorHandler:^(MyNetworkOperation *completedOperation, NSError *error) {
errorBlock(completedOperation, error);
}]; [self.operationArr addObject:op];
- (void) queryMentor:(NSDictionary *)dic
page:(NSInteger)page
rows:(NSInteger)rows
sort:(NSString *)sort
refresh:(BOOL)refresh
{
__unsafe_unretained typeof(self) vc = self; MKNetworkOperation *currentOperation = [[SwycEngine sharedEngine] oralCategoryByLangPage:LangTypeEnglish page:page rows:rows CompletionHandler:^(id object) {
NSArray *arr = object; if (refresh) {
self.page = ;
vc.items = [NSMutableArray arrayWithArray:arr];
} else {
if (arr.count > ) {
self.page++;
[vc.items addObjectsFromArray:arr]; }
}
[vc.tableView reloadData];
// 结束刷新
[self.tableView.mj_footer endRefreshing];
[self.tableView.mj_header endRefreshing]; vc.currentOperation = nil;
} errorHandler:^(NSError *error) {
// 结束刷新
[self.tableView.mj_footer endRefreshing];
[self.tableView.mj_header endRefreshing]; vc.currentOperation = nil;
}]; self.currentOperation = currentOperation; }

唐巧 ios面试题 什么时候在block中不需要使用weakSelf

https://www.zhihu.com/question/34593410

上一篇:Spring集成GuavaCache实现本地缓存


下一篇:把从数据库读出的日期由datetime对象转换为字符串显示到前端