【问题标题】:iOS using self.tableview in block make retain Cycle So leaksiOS 在块中使用 self.tableview 使保留循环因此泄漏
【发布时间】:2014-07-30 12:56:07
【问题描述】:

在我的UITableViewController的加载过程中,我从ServerSingleton类中获取UITableView的数据,带有块,异步网络方法

我将块,当数据提取完成时处理UITableView reloadData,给那个方法

 __weak typeof(MyTableViewController) *weakSelf = self;
 NSURLSessionTask *task = [[ServerSingleton getSharedServerModule] getPostsBestWithCategory:self.categoryNameString
                                                                                          numberOf:10
                                                                                    fromLastPostID:nil
                                                                                          andBlock:^(NSArray *posts_,
                                                                                                     NSError *error) {
                                                                                              if (!error) {

                                                                                                  weakSelf.posts=posts_;
                                                                                                  [weakSelf.tableView reloadData];   /////////Only This row make LEAK!!!!
                                                                                                  [weakSelf addFooterActivity];
                                                                                                  [weakSelf checkAndPlayWithContentOffset];

                                                                                              weakSelf.isLoadingMoreData=false;
                                                                                          }];
        [UIAlertView showAlertViewForTaskWithErrorOnCompletion:task delegate:nil];
        [headRefreshControl setRefreshingWithStateOfTask:task];
    }

下面是ServerSingleTon的方法,当网络请求完成时,它会处理我之前给它的块

- (NSURLSessionDataTask *)getPostsBestWithCategory:(NSString *)categoryName                                
                                           numberOf:(NSInteger)number
                                     fromLastPostID:(NSString *)LastPostID
                                           andBlock:( void (^)(NSArray *posts,
                                                               NSError *error))block{

AFHTTPSessionManager *client=[self getSessionManagerForInsecureDNS];

NSString *urlStr=@"urlString";


return [client GET:urlStr
        parameters:nil
           success:^(NSURLSessionTask *__unused task,id json){
               NSArray *adaptedResult =[self PostArrayAdapterWithObject:json];
               if (block) {
                   block([NSArray arrayWithArray:adaptedResult],nil);
               }
           }
           failure:^(NSURLSessionTask *__unused task,NSError *error){
               if (block) {
                   block([NSArray array],error);
               }
           }];

我的问题是我的自定义 UITableView 控制器进入了保留周期,从而导致泄漏。

我发现我的问题是在块中使用self,所以我把它改成weakSelf,但是它也泄漏了,这是因为调用[weakSelf.tableView reloadData];

当我删除它时,它不会泄漏,但是当该行存在时,它会保持循环并泄漏

什么使泄漏只能访问UITableView?但其他人不是????

我尝试过使用弱类型的UITableView 本身, UITableView 是从 nib 发起的,所以我连接到 __weak 属性

【问题讨论】:

    标签: ios memory-leaks block tableview


    【解决方案1】:

    只是解决同样的问题,你可能想检查tableView:cellForRowAtIndexPath:中的代码,self可能保留在UITableViewCell代码的某个地方,因为唯一的区别是[tableView reloadData]

    【讨论】:

      【解决方案2】:

      您不应该从非主线程调用[UITableView reloadData],这可能是您看到的泄漏的原因:

      if (!error) {
          weakSelf.posts=posts_;
          dispatch_async(dispatch_get_main_queue(), ^{
              [weakSelf.tableView reloadData];
          });                      
          ...
      

      您可能希望在上面的代码中使用dispatch_sync(),具体取决于它之后的那些方法,或者您可能希望将它们添加到调度块中。

      【讨论】:

      • 不,不是这样,完成块已经在主调度队列中执行。所以什么都没有改变。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多