我正在使用递归块来通过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];
}
我可能有保留周期或其他内存泄漏吗? 你知道为什么我的记忆足迹如此之高吗?
谢谢!