有两个属性,如下面
#import <Foundation/Foundation.h>
@interface Contact : NSObject
@property(nonatomic, strong)NSDate *birthDay;
@property(nonatomic, weak)NSDate *birthDay1;
- (void)testWeakProperty;
@end
在实施文件中:
- (void)testWeakProperty {
self.birthDay = [NSDate dateWithTimeIntervalSinceNow:0];
self.birthDay1 = self.birthDay;
self.birthDay = nil;
NSLog(@"_birthday1 is %@, %@", self.birthDay1 , self.birthDay);
}
为什么结果不是_birthday1
是(null), (null)
?
self.birthDay
是常量,则不会取消分配。但有[NSDate dateWithTimeIntervalSinceNow:0]
,
现在我想知道返回值是否为常量以及如何验证声明结果是否为常量和变量。
答案 0 :(得分:2)
这里的关键是你正在处理一个自动释放对象。如果方法名称以init
,copy
,mutableCopy
或new
开头,您将收到一个非自动释放对象。这不是这种情况(您正在使用dateWithTimeIntervalSinceNow
),因此,您将收到一个自动释放对象。
因此,您正在实例化一个autorelease对象,因此在自动释放池耗尽之前不会释放它。在取消分配对象之前,您的弱引用不会是nil
。当您的应用程序返回到运行循环(或者您显式创建自己的自动释放池)时,会发生自动释放对象的释放。
这不是对象是“常数”的问题。你引用的另一个问题是讨论NSString
,它经过大量优化,不符合传统的对象内存管理规则。
您可以通过显式添加自己的自动释放池来更改行为,这会导致在@autoreleasepool
块结束时池被耗尽时取消分配对象,并且您将看到{{1响应:
(null), (null)
您还可以使用非自动释放对象(例如,使用名称以@autoreleasepool {
self.birthDay = [NSDate dateWithTimeIntervalSinceNow:0];
self.birthDay1 = self.birthDay;
self.birthDay = nil;
}
NSLog(@"_birthday1 is %@, %@", self.birthDay1 , self.birthDay);
开头的方法),此非自动释放对象将在设置为init
后立即释放:
nil
这也会显示self.birthDay = [[NSDate alloc] initWithTimeIntervalSinceNow:0];
self.birthDay1 = self.birthDay;
self.birthDay = nil;
NSLog(@"_birthday1 is %@, %@", self.birthDay1 , self.birthDay);
。
答案 1 :(得分:0)
正如Rob解释的那样,重要的一点是你正在使用一个自动释放的对象。
关于他的解释只是一个小精度,[NSDate date...]
实际上是一个简短的(便利)版本:
[[[NSDate alloc] initWith...] autorelease]
其行为与非自动释放的实例不同:
[[NSDate alloc] initWith...]