枚举期间弹出ALAssetslibrary时内存使用率攀升

时间:2012-07-07 02:00:20

标签: iphone 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),虽然定制很多。但是,我刚刚使用该代码进行了测试,同样的问题也发生了。请注意,如果您有足够的ALAsset来枚举,您只会看到内存使用率攀升。如果数量太少,那么在您退出之前它会完成枚举。

谢谢!

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

- (void)enumeratePhotos {       NSAutoreleasePool * pool = [[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]; }

1 个答案:

答案 0 :(得分:0)

纠正我,如果我错了,我认为使用自动释放池应该是这样做的:

@autoreleasepool {
    (statements)
}

这对我有用。