Xcode App doesn't release memory

2019-06-13 18:53发布

问题:

I'm creating an app which stores images in the device (save it as coreData) and I have a problem. every time I choose a picture to add the the collectionView, the memory increases in 100Mb or so, and it increases every time. I think I added the ARC , (Edit->refactor->convert to objective-c ARC..) and it doesn't seem to have any problem adding it, but still the memory doesn't release. Here is my code when image is chosen by the user in uiimagepicker:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {

    UIImage *chosenImage = info[UIImagePickerControllerOriginalImage];

    NSData *imageData = UIImageJPEGRepresentation(chosenImage ,0.2);

    if (imageData != nil)
    {
        AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

        NSString *urlString = [NSString stringWithFormat:@"myurl.."];
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
        [request setURL:[NSURL URLWithString:urlString]];
        [request setHTTPMethod:@"POST"];

        NSString *boundry = @"---------------------------14737809831466499882746641449";
        NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundry];
        [request addValue:contentType forHTTPHeaderField:@"Content-Type"];

        NSMutableData *body = [NSMutableData data];
        [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundry] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userfile\"; filename=\".jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[NSData dataWithData:imageData]];
        [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundry] dataUsingEncoding:NSUTF8StringEncoding]];
        [request setHTTPBody:body];

        //NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
        //NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];

        NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
        NSLog(@"finish uploading");


        NSManagedObjectContext *context = [self managedObjectContext];
        NSManagedObject *newImage = [NSEntityDescription insertNewObjectForEntityForName:@"Images" inManagedObjectContext:context];
        [newImage setValue:imageData forKey:@"image"];

        NSError *error = nil;
        // Save the object to persistent store
        if (![context save:&error]) {
            NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Opps" message:@"There was an error saving the photo.. try again!" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles: nil];
            [alert show];
        }


        [photos addObject:imageData];

        [self.collectionView reloadData];


    }

    [picker dismissViewControllerAnimated:YES completion:NULL];

}

回答1:

  1. When these images are used in collection view cell, you should use image dimensions that correspond to the size of the image view in the cell (times the scale of the device). So, if the image view is 100x100 pt, and the scale is 2.0, you might want to resize the image to 200x200 when loading it into the collection view cell.

    If you don't do that, when you take a high resolution image and use it in a cell, the amount of memory taken is a multiple of the underlying image dimensions, not the size of the image view in the cell. It usually will take four bytes per pixel, e.g. a 3000x2000 pixel image will take 24mb, whereas if it was resized to 200x200 image it will take 160kb. But remember that amount of memory when using the image is far greater than the size of the UIImageJPEGRepresentation.

    This is the image resizing code I use, but feel free to resize it any way you want. Here is a Swift rendition.

  2. While the size of the images is probably the main problem, it should be noted that you should not be holding the image data in an array. You should save some identifier/path that you can use to retrieve the image from a cache and/or persistent storage. But don't try to hold the actual data associated with the images in memory at one time.

    By the way, if you do use something like NSCache for performance reasons, make sure you empty that cache upon memory pressure.

  3. As an aside, if you resize your images, that lessens the need to use using such a low quality in your JPEG compression (which can lead to image quality loss). The dimensions of the image can often have a far greater impact on memory usage than sacrificing quality of the JPEG compression.