0

以下のような2つのプロパティがあります

#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);
}

なぜ結果がそうではないの_birthday1です(null), (null)か?

iOS ARC には弱いプロパティと強いプロパティがあることがわかりました 。定数の場合self.birthDay、割り当ては解除されません。ありますが[NSDate dateWithTimeIntervalSinceNow:0]

今、戻り値が定数であるかどうか、および宣言結果が定数であり変数であることを確認する方法を知りたいです。

4

2 に答える 2

2

ここで重要なのは、autorelease オブジェクトを扱っているということです。initメソッド名が、copymutableCopyまたはで始まる場合new、非自動解放オブジェクトを受け取ります。ここではそうではなく ( を使用していますdateWithTimeIntervalSinceNow)、結果として autorelease オブジェクトを受け取ります。

したがって、自動解放オブジェクトをインスタンス化しているため、自動解放プールが空になるまで割り当てが解除されません。nilまた、オブジェクトの割り当てが解除されるまで、弱参照は処理されません。自動解放オブジェクトの割り当て解除は、アプリが実行ループに戻ったとき (または独自の自動解放プールを明示的に作成したとき) に発生します。

これは、オブジェクトが「定数」であるという問題ではありません。そして、あなたが参照している他の質問は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 に答える