递归块和坏内存泄漏

时间:2014-08-14 16:19:57

标签: ios objective-c automatic-ref-counting objective-c-blocks

我正在使用递归块来通过Twitter API获取推文并且确实遇到了错误的内存泄漏:50次递归提取导致内存占用> 500 MB。

从我的视图控制器内部调用此方法,并控制应该获取时间轴的列表:

    - (void)fetchTweetsForUsersInList:(List*)list withCompletionHandler:
                 (simpleCompletionBlock)completionBlock
{
     [self.managedDocument.managedObjectContext performBlock:^{

     NSFetchRequest *request = [NSFetchRequest 
          fetchRequestWithEntityName:@"User"];
     request.predicate = predicate;
     request.sortDescriptors = sortDescriptors;
     request.shouldRefreshRefetchedObjects = YES;

     NSError *error;
     NSArray *users = [self.managedDocument.managedObjectContext 
          executeFetchRequest:request error:&error];

     __weak __block void (^weakCompletion)(NSError*);
     __block void (^completion)(NSError*);

     __block NSUInteger i = 0;
     __block User *user = users[i];

     unsigned long long since_id = ....;
     unsigned long long maxId = ....;

     completion = ^(NSError *error) {

         if (i == users.count - 1 ) {

            completionBlock(nil); 

         }
         else {
            i++;
            user = users[i];

           [self fetchTimelineOfUser:user 
            sinceId:since_id maxId:maxId 
            withCompletionHandler:weakCompletion];
         }
       };

    weakCompletion = completion;
    [self fetchTimelineOfUser:user 
        sinceId:since_id maxId:maxId 
        withCompletionHandler:completion];
    }];
}

这是递归调用的fetchTimelineOfUser

- (void)fetchTimelineOfUser:(User*)user 
    sinceId:(unsigned long long)since_id 
    maxId:(unsigned long long)maxId 
    withCompletionHandler:(simpleCompletionBlock)completionBlock
{
    TwitterRequest *twitterRequest = self.twitterRequest;

    NSUInteger count = 2000;

    __weak __block void (^weakCompletion)(NSError*, unsigned long long, NSArray*);
    __block void (^completion)(NSError*, unsigned long long, NSArray*);

    completion = ^(NSError *error, unsigned long long  minId, NSArray *tweets) {

        [self.managedDocument.managedObjectContext performBlockAndWait:^{

           [tweets enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

              // Create new Tweet object

              Tweet *tweet = [NSEntityDescription
                  insertNewObjectForEntityForName:@"Tweet"
                  inManagedObjectContext:self.managedDocument.managedObjectContext];
              tweet.text = [obj valueForKey:@"text"];

               NSError *saveError;
              [self.managedDocument.managedObjectContext save:&saveError];

                // (1) If no more tweets above since_id or the minimum 
                // tweet id has reached an existing tweet id, recursion is complete:

                if (tweets.count == 0 || minId - 1 == since_id) {

                    NSError *saveError;
                    [self.managedDocument.managedObjectContext 
                           save:&saveError];

                    [self.managedDocument.managedObjectContext 
                         performBlockAndWait:^{

                        [self.managedDocument saveToURL:self.managedDocument.fileURL
                                       forSaveOperation:UIDocumentSaveForOverwriting
                                      completionHandler:^(BOOL success) {

                                          completionBlock(nil);
                                          return;
                                      }];
                    }];
                }

                // (2) Otherwise RECURSIVELY call ...

                else {
                    [twitterRequest 
                       fetchTimelineForUser:user.screen_name 
                       sinceId:since_id maxId:minId-1 
                       count:count 
                       withCompletion:weakCompletion];
                }
            }];
        }
    };
    weakCompletion = completion;

    [twitterRequest fetchTimelineForUser:user.screen_name 
          sinceId:since_id maxId:maxId 
          count:count 
          withCompletion:completion];
}

问题:

我可能有保留周期或其他内存泄漏吗? 你知道为什么我的记忆足迹如此之高吗?

谢谢!

0 个答案:

没有答案