アップデート2:
今朝、iOS 5プロジェクトでivarがリリースされなかったことを診断して文書化するのに数時間を費やした後、ゾンビがオンになってiOS 5で実行された場合、インスタンス変数がARCプロジェクトでリリースされないことを発見しました。まったく独立して、これらの注目に値する発見で私の答えを更新してください、カリンはこれがよく知られている行動であると私に指摘しました。技術的なQ&AQA1758。カリンありがとう!
私のサンプルプロジェクトはhttps://github.com/robertmryan/arc-problem-projectにあります
アップデート:
以前、これは正しくなく、変数とプロパティはに設定しない限り割り当てが解除されないと主張していましたnil
。例として以下のコードを提供しました。これは実際のARCテストプロジェクトから取得したものであり、確認のために以下のコードを除いてまったく何も含まれていない別のViewControllerを使用して再作成しました。異議を唱えるに値する合唱の後、私はこのコードサンプルを新しいプロジェクトに入れ、ivarの割り当てを解除しました。
したがって、それは問題のプロジェクトに関するものでなければなりません。それ以来、以下のコード(およびプッシュセグを実行するView Controllerを除いて、プロジェクトからすべてを完全に削除しました。これにより、プロジェクトに戻って割り当て解除のデモを行うことができます)、問題は解決しません。コード(およびストーリーボード)を新しいプロジェクトにコピーすると、正常に機能します。非常に、非常に奇妙で、私はこれをさらに掘り下げます。私のプロジェクトを見たい場合は、https://github.com/robertmryan/arc-problem-projectにあります。多分誰か他の人が問題が何であるかを見ることができます。このプロジェクトを破棄することはできますが(本番アプリではなく、テストプラットフォームでした)、ARCのdeallocが魔法のように正しく機能しないのではないかと心配しています。
とにかく、明確にするために、親オブジェクトが解放されると、ivarが解放されます。以下のケースでなぜリリースしないのかわかりませんが、それは元の質問には重要ではありません。
// ArcTestViewController.m
#import "ArcTestViewController.h"
#pragma mark - IvarObject
@interface IvarObject : NSObject
@end
@implementation IvarObject
- (void)dealloc
{
NSLog(@"%s", __FUNCTION__);
}
@end
#pragma mark - ArcTestViewController
@interface ArcTestViewController ()
{
IvarObject __strong *_ivarObject;
}
@end
@implementation ArcTestViewController
- (void)dealloc
{
NSLog(@"%s", __FUNCTION__);
// _ivarObject = nil;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_ivarObject = [[IvarObject alloc] init];
}
@end
コメントアウトさ=nil
れたメソッドのステートメントを使用してこれを行うと、コンソールに次のように表示されます。dealloc
2012-07-12 10:33:33.644 test4 [36045:11903]-[ArcSimpleTestViewControllerdealloc]
=nil
でそのステートメントのコメントを外すとdealloc
、次のように表示されます。
2012-07-12 10:35:23.117 test4 [36083:11903]-[ArcSimpleTestViewControllerdealloc]
2012-07-12 10:35:23.119 test4 [36083:11903]-[IvarObject2dealloc]
上記の私の撤回では、これと同じコードを新しいプロジェクトに配置すると、ゼロであるかどうかに関係なく、deallocが表示されます。
Rob Napierが以下のコードサンプルを提供しました(彼と他の人が時間を割いてくれたことに感謝します)が、上記のコードでも別のプロジェクトに入れると正常に機能しますが、現在のプロジェクトでは適切に割り当てが解除されません!
Rob Napierからの更新:これがどのように機能するかを示す、より単純な例(すべて1つのファイル)。これをファイルに入れて、示されているようにコンパイルします。
// arc.m
// Compile with:
// clang -fobjc-arc -framework Foundation -o arc arc.m
#import <Foundation/Foundation.h>
#pragma mark - IvarObject
@interface IvarObject : NSObject
@end
@implementation IvarObject
- (void)dealloc
{
NSLog(@"%s", __FUNCTION__);
}
@end
#pragma mark - PropertyObject
@interface PropertyObject : NSObject
@end
@implementation PropertyObject
- (void)dealloc
{
NSLog(@"%s", __FUNCTION__);
}
@end
#pragma mark - ArcTest
@interface ArcTest : NSObject
{
IvarObject __strong *_ivarObject;
}
@property (nonatomic, strong) PropertyObject *propertyObject;
@end
@implementation ArcTest
@synthesize propertyObject = _propertyObject;
- (void)dealloc
{
NSLog(@"%s", __FUNCTION__);
// _ivarObject = nil;
// _propertyObject = nil;
}
- (void)assignStuff
{
_ivarObject = [[IvarObject alloc] init];
self.propertyObject = [[PropertyObject alloc] init];
}
@end
int main () {
ArcTest *test = [[ArcTest alloc] init];
[test assignStuff];
test = nil;
NSLog(@"End program");
}