简体   繁体   中英

Objective-c property not released under the ARC

I want to test properties attributes under the arc. I have created two NSString properties under Class1.h (interface file):

@interface Class1 : NSObject
@property (nonatomic, strong) NSString *str1;
@property (nonatomic, weak) NSString *str2;
@end

Then I have created a test method under Class1.m (implementation file):

@implementation Class1

- (void)testMethod {
    NSString *strt1 = @"exampleString1";
    NSString *strt2 = @"exampleString2";

    self.str1 = strt1;
    self.str2 = strt2;

    strt1 = nil;
    strt2 = nil;

    dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, QOS_CLASS_BACKGROUND);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), aQueue, ^{
        [self testMethod2];
    });
}

- (void)testMethod2 {
    NSLog(self.str1);
    NSLog(self.str2);
}
@end

I put a break point in testMethod2 method then check my NSString properties. I assume str2 set nil but after I run the code the result is;

2015-07-03 14:14:04.412 ARCTEST[12303:6239959] exampleString1

2015-07-03 14:14:04.412 ARCTEST[12303:6239959] exampleString2

Can someone explain me why str2 property not released?

Objective-c uses a string literal pool. That is all strings literals that are the same(text) point to the same object(works since strings are immutable). These strings are never deallocated. It will work as expected if you change your assignment of your strt2 to.

NSString *strt2 = [NSString stringWithFormat:@"%@", @"exampleString2"];

Because it's a string literal. It will stay in memory throughout all the application's lifetime. Try another class and you'll see it will be released. And by the way, when dealing with strings you better use copy than strong or weak

Beside the correct answers of Peter and Andrey, I want to add that you can never be sure that an object is deallocated and a weak reference is set to nil .

  • ARC does not promise that an object is released as early as possible.
  • An object could be created in the ARP. In such a case it is not released before returning to the run loop.
  • An object can be cached for re-use.

It is simply the wrong point of view to expect a deallocation. You give up a reference, nothing else. Think in references, not in life time.

If you want a reference to be nil , nil it out. Don't rely on MM, because it is not made for this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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