第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 = 1;
            vc.thingComments = [NSMutableArray arrayWithArray:arr];
        } else {
            if (arr.count > 0) {
                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)(1 * 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 = 1;
            vc.items = [NSMutableArray arrayWithArray:arr];
        } else {
            if (arr.count > 0) {
                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

 

posted @ 2016-12-09 11:51  lianhuaren  阅读(153)  评论(0编辑  收藏  举报