2012-07-07 42 views
1

我遇到了一个问题,在我的应用程序中看到内存使用率攀升(但仪器中没有明显的泄漏)。枚举期间弹出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]; } 

回答

0

纠正我,如果我错了,我想用自动释放池本来是要现在这个样子做:

@autoreleasepool { 
    (statements) 
} 

为我工作。