简体   繁体   中英

IOS about weak and strong, what's the result should be? and constant declare

there are two properties like below

#import <Foundation/Foundation.h>

@interface Contact : NSObject

@property(nonatomic, strong)NSDate *birthDay;
@property(nonatomic, weak)NSDate *birthDay1;

- (void)testWeakProperty;

@end

on implementation file as:

- (void)testWeakProperty {
    self.birthDay = [NSDate dateWithTimeIntervalSinceNow:0];
    self.birthDay1 = self.birthDay;
    self.birthDay = nil;
    NSLog(@"_birthday1 is %@, %@", self.birthDay1 , self.birthDay);
}

why the result is not _birthday1 is (null), (null) ?

I found that iOS ARC - weak and strong properties . if self.birthDay is constant, it will not be deallocated. but there is [NSDate dateWithTimeIntervalSinceNow:0] ,

now I want to know if the return value is constant and how to verify declare result is constant and a variable.

The key here is that you're dealing with an autorelease object. If a method name starts with init , copy , mutableCopy or new , you'll receive a non-autorelease object. This is not the case here (you are using dateWithTimeIntervalSinceNow ) and as a result, you'll receive an autorelease object.

Thus, you are instantiating an autorelease object and therefore it will not be deallocated until the autorelease pool is drained. And your weak reference will not be nil -ed until the object is deallocated. The deallocation of autorelease objects happens when your app yields back to the run loop (or you explicitly create your own autorelease pool).

This not a question of the object being "a constant". And that other question you reference is discussing NSString which, being heavily optimized, does not conform to traditional object memory management rules.

You can change the behavior by explicitly adding your own autorelease pool, which will cause the object to be deallocated when the pool is drained at the end of the @autoreleasepool block, and you'll see your (null), (null) response:

@autoreleasepool {
    self.birthDay = [NSDate dateWithTimeIntervalSinceNow:0];
    self.birthDay1 = self.birthDay;
    self.birthDay = nil;
}
NSLog(@"_birthday1 is %@, %@", self.birthDay1 , self.birthDay);

You can also use a non-autorelease object (eg use a method whose name starts with init ) and this non-autorelease object will be deallocated immediately after being set to nil :

self.birthDay = [[NSDate alloc] initWithTimeIntervalSinceNow:0];
self.birthDay1 = self.birthDay;
self.birthDay = nil;
NSLog(@"_birthday1 is %@, %@", self.birthDay1 , self.birthDay);

This will also show you (null), (null) .

As Rob explaining, the important point is the fact you are using an auto-released object.

Just a small precision about his explanation, [NSDate date...] is in fact a short ( convenience ) version of :

[[[NSDate alloc] initWith...] autorelease]

Which behave differently than an non-autoreleased instance:

[[NSDate alloc] initWith...]

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