我遇到了一个问题,在我的应用程序中看到内存使用率攀升(但仪器中没有明显的泄漏)。枚举期间弹出ALAssetslibrary时内存使用率攀升
我有一个测试项目与两个viewControllers:MainViewController和PhotoViewController。 MainViewController包含一个简单的按钮,通过uinavigationcontroller pushViewController方法简单地推送PhotoViewController。
在PhotoViewController中,我使用ALAssetsLibrary来为图像填充UITableView。我基本上是这样做的两部分。首先,我查看哪些assetGroups可用,因为我需要显示Camera Roll和Photolibrary中的图像。一旦完成,我会调用另一种方法来枚举实际的资产。
这是奇怪的行为:如果我推动PhotoViewController并让它完成整个枚举并填充UITableView,然后弹出回MainViewController,一切都很好。但是,如果我反复快速地推出并弹出PhotoViewCOntroller(虽然它还没有完成枚举和填充UITableiew),但是我看到我的内存使用量逐渐攀升,直到应用程序最终死亡。我在仪器中看不到任何明显的泄漏。
我不知道相关的代码,但这里有两个方法用于枚举。当然,在dealloc中,我正在发布相关的ivars。
是否有某种方法可以在弹出时取消枚举?
就像一个笔记,我将我的测试代码从这个项目(https://github.com/elc/ELCImagePickerController),尽管严重定制。但是,我只是用该代码进行测试并发生相同的问题。请注意,如果您有足够的ALAssets进行枚举,则只会看到内存使用率攀升。如果数量太少,那么它会在您退出之前完成枚举。
谢谢!
- (void)getAssetGroups
{
// Load Albums into assetGroups
dispatch_async(dispatch_get_main_queue(),^
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Group enumerator Block
void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop)
{
if (group == nil)
{
// check what data is available
if([savedPhotosGroup numberOfAssets] > 0 && [libraryGroup numberOfAssets] > 0)
{
// User has both Camera Roll and Photo Library albums
self.tableData = [NSMutableDictionary dictionaryWithObjectsAndKeys:
savedPhotoAssets, NSLocalizedString(@"PHOTOPICKER_CAMERAROLL", nil),
libraryPhotosAssets, NSLocalizedString(@"PHOTOPICKER_PHOTOLIBRARY", nil),
nil];
self.sectionKeys = [NSArray arrayWithObjects:NSLocalizedString(@"PHOTOPICKER_CAMERAROLL", nil), NSLocalizedString(@"PHOTOPICKER_PHOTOLIBRARY", nil), nil];
}
else if([libraryGroup numberOfAssets] == 0)
{
// User only has Camera Roll
self.tableData = [NSMutableDictionary dictionaryWithObjectsAndKeys:
savedPhotoAssets, NSLocalizedString(@"PHOTOPICKER_CAMERAROLL", nil),
nil];
self.sectionKeys = [NSArray arrayWithObjects:NSLocalizedString(@"PHOTOPICKER_CAMERAROLL", nil), nil];
}
else
{
//User only has Photo Library
self.tableData = [NSMutableDictionary dictionaryWithObjectsAndKeys:
libraryPhotosAssets, NSLocalizedString(@"PHOTOPICKER_PHOTOLIBRARY", nil),
nil];
self.sectionKeys = [NSArray arrayWithObjects:NSLocalizedString(@"PHOTOPICKER_PHOTOLIBRARY", nil), nil];
}
NSLog(@"Done enumerating groups");
[self performSelectorInBackground:@selector(enumeratePhotos) withObject:nil];
[self.tview performSelector:@selector(reloadData) withObject:nil afterDelay:1];
return;
}
ALAssetsGroupType groupType = [[group valueForProperty:ALAssetsGroupPropertyType] unsignedIntValue];
if(groupType == ALAssetsGroupSavedPhotos)
{
self.savedPhotosGroup = group;
}
else if(groupType == ALAssetsGroupLibrary)
{
self.libraryGroup = group;
}
};
// Group Enumerator Failure Block
void (^assetGroupEnumberatorFailure)(NSError *) = ^(NSError *error) {
NSLog(@"A problem occured %@", [error description]);
};
// Enumerate Albums
[library enumerateGroupsWithTypes: ALAssetsGroupSavedPhotos | ALAssetsGroupLibrary
usingBlock:assetGroupEnumerator
failureBlock:assetGroupEnumberatorFailure];
NSLog(@"Draining pool");
[pool drain];
});
}
- (无效)enumeratePhotos { NSAutoreleasePool *池= [[NSAutoreleasePool的alloc] INIT];
NSLog(@"enumerating photos"); [savedPhotosGroup enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { if(result == nil) { return; } CustomAsset *customAsset = [[[CustomAsset alloc] initWithAsset:result] autorelease]; [customAsset setParent:self]; [savedPhotoAssets addObject:customAsset]; }]; [libraryGroup enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { if(result == nil) { return; } CustomAsset *customAsset = [[[CustomAsset alloc] initWithAsset:result] autorelease]; [customAsset setParent:self]; [libraryPhotosAssets addObject:customAsset]; }]; NSLog(@"done enumerating photos"); [tview performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO]; // only do this if I want to re-select some assets if(assetsToRestore) { for(NSDictionary *dict in assetsToRestore) { NSIndexPath *indexPathToRestore = [dict objectForKey:@"selectedAssetIndexPath"]; int tagToRestore = [[dict objectForKey:@"selectedAssetTag"] intValue]; [self selectAssetWithIndexPath:indexPathToRestore andIndex:tagToRestore]; } } [pool drain]; }