Eli
Eli

Reputation: 626

Should @autoreleasepool function could be used manually for memory managment?

I'm currently building an app that pulls large JSON file via an API request.

During the download-decoding-storing the data I get memory warnings (over 500MB).I found a solution to avoid to overload the memory and keep it at most at 300MB by adding @autoreleasepool { } function manually.

@autoreleasepool {
    NSString * result = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&err];//150
    decodeData = [[NSData alloc] initWithBase64EncodedString:result options:0];//100
}

@autoreleasepool {
    NSString * decodeString = [[NSString alloc] initWithData:decodeData encoding:NSUTF8StringEncoding];//100

    NSError * jsonError;
    NSData * objectData = [decodeString dataUsingEncoding:NSUTF8StringEncoding];//100
    json = [NSJSONSerialization JSONObjectWithData:objectData options:NSJSONReadingMutableContainers error:&jsonError];//50
    if(!jsonError){
        [defults setObject:json forKey:@"data_object"];//50
    }
}

Is there a better way of doing this for memory management?

Upvotes: 1

Views: 338

Answers (1)

Avi
Avi

Reputation: 7552

Placing an @autorelease block around code that generates lots of throw-away (autoreleased) objects is not only valid, but recommended. This obviously also applies to few, large objects :)

Code which is running on the main thread has an autorelease pool available, but it may not be enough. The pool is drained at the bottom of the runloop, and if many autoreleased objects are created in a single runloop cycle, you may need a pool specifically to cleanup these objects to avoid running out of memory. This happens often with loops, and it's recommended that loop bodies be @autorelease blocks in such situations.

In terms of your specific issue, 300MB for one JSON structure is pushing it. If at all possible, you should try and break that up into smaller objects and parse them separately.

Upvotes: 2

Related Questions