user3572235
user3572235

Reputation: 51

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?

Upvotes: 1

Views: 136

Answers (3)

Amin Negm-Awad
Amin Negm-Awad

Reputation: 16650

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.

Upvotes: 0

Peter Segerblom
Peter Segerblom

Reputation: 2813

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"];

Upvotes: 6

Andrey Chernukha
Andrey Chernukha

Reputation: 21808

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

Upvotes: 3

Related Questions