3

ARCを使用してObjective-Cでアプリを開発しています。

私の簡略化されたコードは次のようになります。

ClassA(.m)

MyCustomClass *obj = [[MyCustomClass alloc] initWithValue1:@"abc" value2:1000];
MyViewController *vc = [[MyViewController alloc] initWithObject:obj];
// "vc" will become the first item of a UITabBarController

MyViewController(.h)

- (id)initWithObject:(MyCustomClass *)obj {
    ...
    localReferenceToOjbect = obj;
    ...
}

- (void)viewWillAppear:(BOOL)animated {
    // do something with "localRefernceToObject" <---
}

アプリを起動するとゾンビが呼び出されます。ViewControllerが表示されると、「obj」の割り当てが解除されているため、使用できなくなります。

私の回避策は次のとおりです。

ClassA(.h)

@interface ClassA : UIViewController {
    MyCustomClass *obj;
}

ClassA(.m)

obj = [[MyCustomClass alloc] initWithValue1:@"abc" value2:1000];
MyViewController *vc = [[MyViewController alloc] initWithObject:obj];
// "vc" will become the first item of a UITabBarController

これは正しい方法ですか?!私はそうは思いません:なぜ私はClassAに役に立たないオブジェクトのインスタンスを保存しなければならないのですか?
実際に何が起こっているのか説明がつかない。私たちを手伝ってくれますか?

4

1 に答える 1

1

ClassA で obj への参照を保持することは論理的ではないという事実は正しいです。

ただし、MyViewController で使用するために obj への参照を保持する必要がある場合は、ClassA ではなく MyViewController で保持します。これは、それを使用する MyViewController であるためです。

これを行う最も簡単な方法は、使用する を に変換localReferenceToObjectMyViewController(@property(retain) propertyToObject;または@property(strong) propertyToObjectARC を使用する場合)、MyViewController.mwith でアクセスすることですself.propertyToObject( の代わりにlocalReferenceToObject、プロパティのセッターを呼び出して、実際にオブジェクトを保持するようにしてください)。

このようにして、オブジェクトは保持され、MyViewControllerインスタンスがまだ生きている間保持されます。


[編集]このプロパティをプライベートにしたい場合は、以下の例のように、他のクラスからアクセスできないようにクラス拡張で宣言できます。詳細については、Apple のドキュメントのこちらを参照してください。

MyViewController.h ヘッダー ファイル内

@interface MyViewController : UIViewController
// Here you write the public API in the .h / public header
// If you don't want your property to be visible, don't declare it there
@end

MyViewController.m ファイル内

@interface MyViewController ()
// This is the private API, only visible inside the MyViewController.m file and not from other classes
// Note the "()" to declare the class extension, as explained in Apple doc
@property(nonatomic, retain) MyCustomClass* referenceToObject; // Note: use strong (which is a synonym of retain) if you use ARC
@end

@implementation MyViewController
@synthesize referenceToObject = _referenceToObject; // not even needed with modern ObjC and latest LLVM compiler

- (id)initWithObject:(MyCustomClass *)obj
{
    self = [super init];
    if (self) {
        ...
        self.referenceToOjbect = obj;
        ...
    }
    return self;
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    // do something with "self.refernceToObject"
}

// This memory management code is only needed if you don't use ARC
-(void)dealloc
{
    self.referenceToObject = nil; // release memory
    [super dealloc];
}

個人的には、いくつかの WWDC セッションで Apple が示唆したように、私は今ではインスタンス変数をほとんど使用せず、代わりにプロパティを使用することを好みます。


strongARC を使用する場合でも、プロパティの代わりにインスタンス変数を使用できます。ただし、インスタンス変数が ではなくとして宣言されていることを確認する限り、ARC はそれを保持しますweak

于 2012-10-18T09:19:08.503 に答える