0

有两个属性,如下所示

#import <Foundation/Foundation.h>

@interface Contact : NSObject

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

- (void)testWeakProperty;

@end

实现文件为:</p>

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

为什么结果不是_birthday1is (null), (null)

我发现 iOS ARC 的弱和强属性。如果self.birthDay是常量,则不会被释放。但是有[NSDate dateWithTimeIntervalSinceNow:0]

现在我想知道返回值是否为常量以及如何验证声明结果是常量和变量。

4

2 回答 2

2

这里的关键是您正在处理一个自动释放对象。如果方法名称以init、或开头copy,您将收到一个非自动释放对象。这不是这里的情况(您正在使用),因此,您将收到一个自动释放对象。mutableCopynewdateWithTimeIntervalSinceNow

因此,您正在实例化一个自动释放对象,因此在自动释放池耗尽之前它不会被释放。nil在对象被释放之前,您的弱引用不会被-ed。当您的应用程序返回到运行循环(或者您显式创建自己的自动释放池)时,会发生自动释放对象的释放。

这不是对象是“常数”的问题。您引用的另一个问题是讨论NSString哪些经过大量优化不符合传统的对象内存管理规则。

您可以通过显式添加自己的自动释放池来更改行为,这将导致在@autoreleasepool块结束时池被耗尽时释放对象,您将看到您的(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);

这也会告诉你(null), (null)

于 2014-06-28T12:16:08.413 回答
0

正如 Rob 解释的那样,重要的一点是您使用的是自动释放的对象。

关于他的解释只是一个小小的精确,[NSDate date...]实际上是一个简短的(方便)版本:

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

其行为与非自动释放实例不同:

[[NSDate alloc] initWith...]
于 2014-06-28T08:15:29.867 回答