Question

I'm trying to load in about 70 images. I'm doing this in a background thread, reading them in and writing them to the local sandbox. I'm using the following two lines to read in and then write to a file.

NSData *imagedata = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imageurl]];
[imagedata writeToFile:path atomically:YES];

This works fine but I notice the memory is spiking during the load, reaching 16MB by the end of the load, as shown in instruments. After I finish loading, the memory comes down and stays down. In the future, the number of images I need to load may increase. Should I be worried? I've tried several different ways to read the images and several ways of writing the file. I've also tried wrapping the code in an @autoreleasepool but it doesn't help. I'm using ARC, app is for both iOS 6 and 7.

Images are mostly 50-100K each, 150K is the largest.

Any suggestions would be much appreciated.

Here is more of the code:

- (void)getAllNewImagesAtLoad:(NSMutableArray *)arr {
    @autoreleasepool {
        // NSData *imagedata;  tried defining variable here initially but didn't help
        for (int i=0;i<[arr count];i++) {

            int picID = [[arr valueForKey:@"PictureID"][i] intValue];
            NSString* path = [helper tempPathForImage:picID];

            if ([[arr valueForKey:@"DelFlag"][i] isEqualToString:@"delete"]) {
                if ([[NSFileManager defaultManager] fileExistsAtPath:path] == YES) {
                    [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
               }
            } else if ([[NSFileManager defaultManager] fileExistsAtPath:path] == YES) {
                // do nothing
            } else {
                NSData *imagedata = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imageurl]];
                [imagedata writeToFile:path atomically:YES];
                imagedata = nil;
            }
            NSNumber *val = [NSNumber numberWithInt:(int)(((i+1)*100)/[arr count])];
            [self performSelectorOnMainThread:@selector(updateFunction:) withObject:val waitUntilDone:NO];
        }
    }
}

I did try the imagedata=nil idea but that didn't help. I also tried pulling out the two lines of initWithContentsOfURL and writeToFile into their own method and wrapping just that in an autoreleasepool, but didn't help.

In instruments, I'm watching the "live bytes" increase to over 16MB by the end of the load and then dropping down to 2.5MB as soon as load finishes.

Was it helpful?

Solution

I am not sure it will help or not but anyway you should move @autoreleasepool inside the 'for' loop, because now it has not so much sense:

- (void)getAllNewImagesAtLoad:(NSMutableArray *)arr {

    // NSData *imagedata;  tried defining variable here initially but didn't help
    for (int i=0;i<[arr count];i++) {
        @autoreleasepool {

        int picID = [[arr valueForKey:@"PictureID"][i] intValue];
        NSString* path = [helper tempPathForImage:picID];

        if ([[arr valueForKey:@"DelFlag"][i] isEqualToString:@"delete"]) {
            if ([[NSFileManager defaultManager] fileExistsAtPath:path] == YES) {
                [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
           }
        } else if ([[NSFileManager defaultManager] fileExistsAtPath:path] == YES) {
            // do nothing
        } else {
            NSData *imagedata = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imageurl]];
            [imagedata writeToFile:path atomically:YES];
            imagedata = nil;
        }
        NSNumber *val = [NSNumber numberWithInt:(int)(((i+1)*100)/[arr count])];
        [self performSelectorOnMainThread:@selector(updateFunction:) withObject:val waitUntilDone:NO];
    }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top