5

次のようなビューコントローラがあるとします。

@interface ControllerA : viewcontroller{
    NSString * __strong a;
}

@end

そしてviewDidLoad機能で私は設定しました

a = [[NSSString alloc] init];

そして別のControllerBでは、

{
    ControllerA * controllerA = [[ControllerA alloc] init];
}

controllerAのメンバーは解放されますか?

4

4 に答える 4

5

はい、が指す文字列は、割り当てが解除aされると解放されcontrollerAます。自分で設定する必要はありませんnil

ARCリリースノートへの移行は、現在、ARCの操作に関する詳細情報を探す場所です。重要な点の1つは、インスタンスの割り当てが解除されたときに-deallocクラスがインスタンス変数を解放する以外のことを行う必要がある場合でも、カスタムが必要になる可能性があるということです。

于 2012-07-12T04:37:39.767 に答える
4

できるだけ早く割り当てを解除する必要がない限り、ARCで変数をnilに設定する必要はありません(つまり、非ARCコードでの[myObjectリリース])。オブジェクトの割り当てが解除されると、すべてのiVarが自動的に解放されます。

于 2012-07-12T04:34:40.430 に答える
2

iOS 5でARCとゾンビを有効にすると、ivarのリリースを妨げる可能性のあるよく知られたバグがあります:技術的なQ&AQA1758

それ以外の場合、ivarは自動的に解放されます。

于 2013-02-28T14:49:14.740 に答える
1

アップデート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");
}
于 2012-07-12T13:25:59.887 に答える