2012-07-03 9 views
7

保持したいすべてのインスタンス変数をプライベートプロパティに変換する必要がありますか、わかりやすいものがありませんか?この例ではObjective C ARCとインスタンス変数iOS SDK

@interface SomethingElse : Something { 

    NSMutableArray *someArray; 

} 

、someArrayは[NSMutableArrayのinitWithObject:SomeObjectの]と方法で初期化されるが、保持されていません。

私の特定の状況は、ゲームを更新しています。インスタンス変数がたくさんあるので、将来のバージョンのsdkのためにこれを行うようにしたいと思います。

答えて

1

retainのARCのバージョンはstrongと呼ばれます。

基本的に、あなたは次のようなものを使用してそれを宣言します:

@property (strong) NSMutableArray *someArray; 

詳細についてはWhat does the "strong" keyword doを参照してください。

ローカル変数の代わりにプロパティを使用する方が一般的に適しています。これは、プロパティでアクセサー/セッターの「空き」が得られ、一般的に使いやすいためです。

+0

ありがとう、私はARCがどのようにプロパティで動作するかを理解していますが、私の質問は実際にローカル変数をプライベートプロパティに置き換える必要があるかどうかを判断することです。 –

+0

@BillKervaski:一般的に、はい。編集 – houbysoft

+0

を参照してください必要がない限り、明示的に変数を宣言しないことをお勧めします。プロパティを使用し、iVarに直接アクセスする必要がある場合は、プロパティを合成するときにivarの名前を設定することができます。たとえば:@synthesize myProperty = __myVariable – isaac

0

Obj-C 2.0以降では、iVarsを使用する理由はほとんどありません。私は個人的に永遠に1つを使用していません。プロパティはあなたのためにすべてを行います!

+0

iVarsを使用する理由はたくさんあります。リストのトップ:ハッカーが実行時にdylibでコードを壊してしまい、Cスタイルの配列が容易になり、プロパティよりも軽いハッカーにとってははるかに難しくなります。 –

+0

@ RichardJ.RossIII:iVarsセキュリティに関して:iOSサンドボックス環境にも適用されますか? – user523234

+0

@ user523234はい。 jailbrokenデバイスを持つ人は実行したくないコードを実行することができます。プロパティの代わりにiVarsを使用すると、コードを実行するのがずっと難しくなります。 –

15

を保持するローカル変数をすべて私的なプロパティに変換する必要がありますか、わかりやすいものがありませんか?

まず、あなたの例で示した変数は、ローカル変数ではなくインスタンス変数です。ローカル変数は、コードブロック内で宣言されています(関数やメソッド内部、または条件文の本体などのサブブロック内など)。宣言されているブロックの実行に制限されています。インスタンス変数はクラス内で宣言されています。各インスタンスは、クラスによって宣言されたインスタンス変数のコピーを取得します。

第2に、いいえ、すべてのインスタンス変数をプロパティに変換する必要はありません。 Instance variables are treated as strong references by default under ARC.プロパティは、クラスが特定のセマンティクスを持つ特定のアクセサを提供するということのほんの約束です。インスタンス変数を持っていても、そのivarにアクセサを用意しなければならないわけではありません。

+0

ありがとう、編集された質問は、インスタンス変数を正しく反映します。私はそのインスタンス変数をデフォルトで強く読んでいますが、私の例ではオブジェクトは逆参照されています(つまり、BAD_ACCESS)、これは私が今混乱しているように投稿するように促しました。 –

3

@propertyは、オブジェクトに強いデフォルトのstorage修飾子以外を使用しない限り、インスタンス変数と同じです(ある場合は、になるはずです)。たとえば、@property (copy) NSString *s;にインスタンス変数を使用し、変数を設定するたびにcopyを呼び出すか、@propertyを使用する(これは簡単です)。

+0

これは、 '@ property'を使用するとプライベート変数を意味する唯一の状況です。 +1。 –

+0

c/local/instance/ –

1

他のコメントの中には、BAD_ACCESSの問題が記述されています。ここには何か他のことがあります。 ARCでは、あなたのイヤーズは、他に認定されていない限り強力です(ARC以外では、あなたのためにリリースされません)。例えば

、このARCコードを使用すると、他の回答にコメントで報告していないBAD_ACCESSと、正常に動作します:

@interface ArcTestViewController() 
{ 
    NSMutableArray *_someArray; 
} 
@end 

@implementation ArcTestViewController 

- (void)dealloc 
{ 
    _someArray = nil; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    _someArray = [[NSMutableArray alloc] initWithObjects:@"Mo", @"Larry", @"Curly", nil]; 
} 

- (IBAction)checkIvarTouchUpInside:(id)sender 
{ 
    NSLog(@"%s _someArray = %@", __FUNCTION__, _someArray); 
} 

@end 

あなたはそれのであなたのBAD_ACCESSを取得している場所を私達にあなたの例を表示する必要がある場合があります何か他のものでなければならない。

「プロパティ」または「ivar」の質問に対する回答では、「常にプロパティを使用する」引数に同感していますが、個人的に私は外部アクセサを提供する必要があるものはすべてプロパティを使用し、 ivars(.hではなく、.mファイルのプライベートインタフェース)。これにより、私の.hファイル内の私の公開インターフェースは、実際にきれいになり、数か月後に戻ってくると分かりやすくなります。 「常にプロパティを使用する」アプローチを採用する場合は、そのプロパティの公開宣言を可能な限り制限するようにアドバイスするだけです(できる場合はプロパティを非公開にし、不在の場合はプロパティの公開宣言を読みやすくする読み書きアクセスなどを提供する必要がありません)。

ちなみに、ココアのコーディングガイドラインNaming Properties and Data Typesはベストプラクティスの参考になります。

0

ご回答いただきありがとうございます。

私は(cocos2dゲームエンジンの方法を使用して)を持つオブジェクトを必要とするメソッドを呼び出す場合:

[self schedule:@selector(someMethod) interval:3.0]; 

私はcocos2dスケジューラでそれを入れずに直接呼び出す場合、オブジェクトは、間接参照されます。

[self someMethod]; 

それでも有効なポインタがあります。ちょうどテストするために、私はそれを保持し、それは周りにとどまります。

これで、ARCが完了したと思って解放することを防ぐために、どのようにして保持する必要がありますか。

インスタンス変数をプライベートプロパティに変更するのは安全ですので、これを答えにします。

+0

ちょうど説明のために、ivarを@propertyに切り替えると実際に問題が解決されると言いますか?私の問題は、保持されていないNSMutableDictionaryのオブジェクトです。 – rrbrambley

関連する問題