简体   繁体   中英

iOS using self.tableview in block make retain Cycle So leaks

in my UITableViewController 's loading Process, i fetch UITableView 's Data From ServerSingleton Class With Block, async network method

i give block, which Process UITableView reloadData when data fetch Done, to that method

 __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];
    }

and this below is ServerSingleTon's method and when network request done, it process block which i gave it before

- (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);
               }
           }];

my problem is that my custom UITableView controller get in retain Cycle thus cause leak.

I figure out my problem is using self in block, so i change it to weakSelf, But It leaks too, and it was because of calling [weakSelf.tableView reloadData];

when i delete this, it doesn't leak , but when the line exist it make retain cycle and leak

what make leaks only to access UITableView ? but others not????

i have tried using weak type of UITableView itself, and UITableView is initiated from nib so i connect With __weak property

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

You should not call [UITableView reloadData] from a non-main thread, and this may be the cause of the leak you are seeing:

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

You may want to use dispatch_sync() in the above code, depending on what those methods after it do, or you may want to add them into dispatched block.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM