简体   繁体   English

ios应用程序内存不足

[英]ios app running out of memory

I am working on an app that imports photos from photo library. 我正在开发一个从照片库导入照片的应用程序。 While importing the photos its using up alot of memory and after importing 160 photos it crashes. 导入照片时,使用大量内存,导入160张照片后会崩溃。

I dont know why is this happening. 我不知道为什么会这样。 Any help would be much appreciated. 任何帮助将非常感激。

Here is my code 这是我的代码

- (void)agImagePickerController:(AGImagePickerController *)picker    didFinishPickingMediaWithInfo:(NSArray *)info{

[pickerView dismissViewControllerAnimated:YES completion:nil];
[self.navigationItem setHidesBackButton:YES];
[self.navigationItem.rightBarButtonItem setEnabled:NO];

MBProgressHUD * hud =  [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText=@"Importing Your Photo(s)";



// USING GRAND CENTRAL DISPATCH

firstQueue=dispatch_queue_create("com.import.photos", nil);
dispatch_async(firstQueue, ^{

    [self beingBackgroundUpdateTask];

    // Open connection
    //[albumObject openDB];


    // Start the loop from here ******************************************************
    int j=0;
    for(j=0;j<info.count;j++){

        // update the hud label
        hud.labelText=[[NSString alloc] initWithFormat:@"Importing %i of %i",j+1, [info  count]];


        // Create new image from returned array
        ALAssetRepresentation *rep = [[info objectAtIndex: j] defaultRepresentation];
        UIImage * image  = [UIImage imageWithCGImage:[rep fullScreenImage]];
        //rep=nil;

        // resize the image for the thumbnail and save it in new image
        UIImage *newImage=[image  resizedImageWithContentMode:UIViewContentModeScaleAspectFill bounds:CGSizeMake(75, 75)  interpolationQuality:kCGInterpolationDefault];


        NSDate *date = [NSDate date];

        NSDateFormatter *dateFormat = [[NSDateFormatter alloc]init];
        [dateFormat setDateFormat:@"DD_MM_YY_HH_mm_ss"];
        NSString *dateString = [dateFormat stringFromDate:date];

        int random=rand();
        // create new file names
        NSString *fileName=[[NSString alloc] initWithFormat:@"%d%@",random,dateString];
        NSString *s_fileName=[[NSString alloc]  initWithFormat:@"small_%d%@",random,dateString];
        // where to save this image
        NSString *imagePath=[self.documentsDirectory  stringByAppendingPathComponent:fileName];
        NSString *s_imagePath=[self.documentsDirectory stringByAppendingPathComponent:s_fileName];


        NSLog(@"type: %@",[rep.url pathExtension]);

        if ([[rep.url pathExtension] isEqualToString:@"JPG"]) {
            // its jpg
            NSData *rawImage=UIImageJPEGRepresentation(image, 1.0);
            NSData *thumb=UIImageJPEGRepresentation(newImage, 1.0);


            image=nil;
            newImage=nil;
            date=nil;
            dateFormat=nil;
            dateString=nil;
            random=nil;

            // Create the images
            [rawImage writeToFile:imagePath atomically:YES];
            [thumb writeToFile:s_imagePath atomically:YES];

            imagePath=nil;
            s_imagePath=nil;
            rawImage=nil;
            thumb=nil;

        }

        if ([[rep.url pathExtension] isEqualToString:@"PNG"]) {
            // its PNG
            // save it in NSData to it can be saved in the directory
            NSData *rawImage=UIImagePNGRepresentation(image);
            NSData *thumb=UIImagePNGRepresentation(newImage);




            image=nil;
            newImage=nil;
            date=nil;
            dateFormat=nil;
            dateString=nil;
            random=nil;

            // Create the images
            [rawImage writeToFile:imagePath atomically:YES];
            [thumb writeToFile:s_imagePath atomically:YES];

            imagePath=nil;
            s_imagePath=nil;
            rawImage=nil;
            thumb=nil;

        }





        // Now save it to database


        [albumObject savePhoto:fileName toFID:PassedID toName:s_fileName  albumName:singletonObj.currentAlbum photosName:singletonObj.currentPhotos];


        [display_photos addObject:[MWPhoto photoWithFilePath:[self.documentsDirectory  stringByAppendingPathComponent:fileName]]];

        UIImage *img=[UIImage imageWithContentsOfFile:[self.documentsDirectory  stringByAppendingPathComponent:s_fileName]];

        [collection_photos addObject:img];

        img=nil;

        NSArray *pObj=[[NSArray alloc] initWithObjects:fileName,s_fileName, nil];
        [photos addObject:pObj];

        pObj=nil;
        fileName=nil;

        s_fileName=nil;


    } j=nil;

    // Update the album photo count to reflect the changes
    [albumObject updateAlbumCount:PassedID photocount:[photos count]  albumName:singletonObj.currentAlbum];
    photos=[albumObject getPhotos:PassedID photosName:singletonObj.currentPhotos];

    // End the loop here ***************************************************************

    dispatch_async(dispatch_get_main_queue(), ^{
    [self.collectionView reloadData];
    [MBProgressHUD hideHUDForView:self.view animated:YES];
    [self.navigationItem setHidesBackButton:NO];
    [self.navigationItem.rightBarButtonItem setEnabled:YES];

    });

    });



}

In the loop, a lot of extra objects are being generated, and they are not released until the whole loop is finished. 在循环中,生成了许多额外的对象,并且在整个循环完成之前它们不会被释放。 But it never finishes because the extra objects just keep piling up until you run out of memory. 但它永远不会完成,因为额外的对象只是在内存耗尽之前不断堆积。 The first line of defence is to wrap the interior of the loop in an @autoreleasepool block. 第一道防线是将循环内部包装在@autoreleasepool块中。

For an example, look at this section of my book: http://www.apeth.com/iOSBook/ch12.html#_autorelease Scroll down to the bottom of that section. 例如,请查看我的书的这一部分: http//www.apeth.com/iOSBook/ch12.html#_autorelease向下滚动到该部分的底部。

for /* loop iterator goes here */ {
    @autoreleasepool {
        // everything inside the for loop goes here
    }
}

EDIT: I have another suggestion: Are you ending up with an array of images or something like that? 编辑:我有另一个建议:你最终得到一系列的图像或类似的东西? I can't quite tell. 我不能说。 If so, then instead of storing images in memory as the ultimate result of all this, keep the images on disk and store their URLs or file paths instead. 如果是这样,那么不要将图像存储在内存中作为所有这些的最终结果,而是将图像保存在磁盘上并存储其URL或文件路径。 That way you only fetch the images when you need them. 这样您只需在需要时获取图像。 Images take a lot of room in memory, and it goes up exponentially with the size. 图像在内存中占用了大量空间,并且随着大小呈指数增长。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM