ios - Memory Growth Mystery (Objective-C) -


i have memory growth issue in app.

since describing full code here intimidating, narrowed down simple scenario switch , forth between 2 view controllers learn basic memory dynamics.

  - (void)viewdidload {     [super viewdidload];

(int i=0; i<100000; i++) { __weak nsstring* str = [nsstring stringwithformat:@"abcsdf"]; str = nil; } }

this supposed show no memory growth, because allocate 'str' , deallocate 'str' making 'str' becomes nil, losing owner.

but, memory keeps growing. everytime load view controller, memory keeps growing , never coming back.

can tell me why that? using arc.

your code snippet includes several interesting things ios/os x memory management.

__weak nsstring* str = [nsstring stringwithformat:@"abcsdf"]; str = nil; 

the code same following without arc.

nsstring* str = [[[nsstring alloc] initwithformat:@"abcsdf"] autorelease]; str = nil; 

because stringwithformat: class method not begin "alloc", "new", "copy", or "mutablecopy". it's naming rule. nsstring object retained autorelease pool. autorelease pool might in main runloop. nsstring object not deallocated immediately. causes memory growth. @autoreleasepool solves it.

@autoreleasepool {     __weak nsstring* str = [nsstring stringwithformat:@"abcsdf"];     str = nil; } 

the nsstring object deallocated @ end of @autoreleasepool code block.

by way, [nsstring stringwithformat:@"abcsdf"] might not allocate memory every time. reason it's static string. let's use class further explanation.

#import <foundation/foundation.h>  @interface test : nsobject + (instancetype)test; @end  @implementation test - (void)dealloc {     nslog(@"test dealloc"); }  + (instancetype)test {     return [[test alloc] init]; } @end 

here test code __weak.

@autoreleasepool {     nslog(@"begin: = [test test]\n");     __weak test *a = [test test];     nslog(@"end: = [test test]\n");     = nil;     nslog(@"done: = nil\n"); } 

the result of code.

begin: = [test test] end: = [test test] done: = nil test dealloc 

you said deallocate 'str' making 'str' becomes nil, losing owner. not correct. a weak variable doesn't have ownership of object. autorelease pool have ownership of object. that's why object deallocated @ end of @autoreleasepool code block. take @ other test code case.

nslog(@"begin: = [[test alloc] init]\n"); __weak test *a = [[test alloc] init]; nslog(@"end: = [[test alloc] init]\n"); = nil; nslog(@"done: = nil\n"); 

you can see compilation warning code.

warning: assigning retained object weak variable; object          released after assignment [-warc-unsafe-retained-assign]             __weak test *a = [[test alloc] init];                          ^   ~~~~~~~~~~~~~~~~~~~ 

[[test alloc] init] doesn't register object autorelease pool. well, no need @autoreleasepool more. , a __weak variable, object not retained anything. result is

begin: = [[test alloc] init] test dealloc end: = [[test alloc] init] done: = nil 

no ownership no life. object deallocated after allocated. think wanted write code without __weak following.

nslog(@"begin: = [[test alloc] init]\n"); test *a = [[test alloc] init]; nslog(@"end: = [[test alloc] init]\n"); = nil; nslog(@"done: = nil\n"); 

the result expected. object released assigning nil strong variable a. no 1 has ownership of object, object deallocated.

begin: = [[test alloc] init] end: = [[test alloc] init] test dealloc done: = nil 

Comments

Popular posts from this blog

OpenCV OpenCL: Convert Mat to Bitmap in JNI Layer for Android -

python - How to remove the Xframe Options header in django? -

android - org.xmlpull.v1.XmlPullParserException: expected: START_TAG {http://schemas.xmlsoap.org/soap/envelope/}Envelope -