2011-06-24 10 views
1

インスタンス変数を宣言する必要がある理由を理解するのが苦労しています。後者の例では、私はONLY建て..あなたが見ることができるように、これはObjective Cのインスタンス変数、なぜそれらを宣言すべきですか?

@interface LearningViewController : UIViewController { 
    //instance variables go here, but are not declared, I just leave this field blank 
} 

@property (nonatomic,retain) IBOutlet UILabel *myText; 

-(IBAction)method:(id)sender; 

@end 

としてもを行うことができます

@interface LearningViewController : UIViewController { 
    UILabel *myText; // <--- Instance Variables 
} 

@property (nonatomic,retain) IBOutlet UILabel *myText; 

-(IBAction)method:(id)sender; 

@end 

..私は例えば..私は何を意味するか

を説明しましょうsetter/getter for the UILabel * myText

しかし前者ではインスタンス変数も宣言していました。

どちらも、今、両方のものが同じ結果を生成し、エンド

@implementation LearningViewController 

@synthesize myText; 


-(IBAction)method:(id)sender { 
    [myText setText:@"hey"]; 

    //or 

    NSString *myObject = [[NSString alloc]initWithString:@"hey"]; 

    [myText setText:myObject];  
} 

で働いて終わります。だから私の質問は、なぜですか?いずれかの方法でメリットがあるのは何ですか? そして、なぜ私が構築し、私は事前に

[myText setText:@"hey"]; 

おかげで行うことができるとき

NSString *myObject = [[NSString alloc]initWithString:@"hey"]; 

myText.text = myObject; 

オブジェクトです。

答えて

0

コードでは、技術的に、のほとんどの場合、というインスタンス変数を宣言する必要はありません。

これは、古い(< 4.0)iOSランタイムと、インスタンス変数の合成をサポートしていないGCCを使用している32ビットMac OS Xランタイム用にコンパイルするときの唯一の例外です。

さらに、インスタンス変数を後で追加するための領域を確保する場合(フレームワークを作成しており、後でそのクラスを拡張する場合に関係します)、インスタンス変数を明示的に宣言する必要があります。

編集:短い説明:従来の移植性と拡張性に関する懸念は、明示的な象牙の禁止です。 アプリケーションの場合は、10.6、特に10.7をターゲットにして、宣言する必要はほとんどまたはまったくありません。

+0

私の記事を編集してくれてありがとうJhaliya、私はかなり新しくなっています。(あなたが必要としている場所で情報を隠すことと、ドット表記を使うことの両方で)ここでそれは質問をすることになると(それは私の最初のことです)そして、ありがとうウィリアムその素早い答えのために。 – Andy

+1

iOSは現代のランタイムを使用しているので、iOSの合成されたivarsに頼るのはいいです。以前はiOSシミュレータで古いランタイムが使用されていたため、シミュレータを使用していた場合は合成されたivarsを使用できませんでしたが、もはやそうではありません。 – Caleb

+0

@カレブ:確かに;この事実を反映するように答えが更新されました。 –

0

質問の2番目の部分では、単にドット表記を使用しています。 2番目の例と同じように、myText.textを@ "hey"に設定することができます。

[myText setText:@"hey"]; 

あなたは事前にあなたの価値を保持するためにNSStringのを宣言する必要はありません

myText.text = @"hey"; 

と同義です。

1

元々Objective-Cにはプロパティがなく、@ synthesizeは存在しませんでした。あなたはあなたのiVar(インスタンス変数)を宣言し、独自のセッターとゲッターを書く必要がありました。

プロパティと@synthesizeを含めるように言語とランタイムが変更されたとき、物事は良くなりました。あなたはセッターとゲッターを書く必要がなくなりました。しかし、あなたはまだあなたのiVarを宣言しなければならなかった。

さらに言語とランタイムがさらに進化し、iVarを宣言する必要はありません。 (私は@synthesize example = _exampleを書く傾向がありますので、生成されたiVarの名前を制御できます)。

これは新機能であり、比較的最近のバージョンのランタイムでのみサポートされています。 OSXの旧バージョンと同様に、4.x未満のiOSバージョンはサポートされていません。あなたはアイバーズを残すことができます

あなたはYOTは、レガシーサポートが必要な場合は、それらを残して、先に行くと、それらを残して、今日および将来のためのソフトウェアを構築している場合。

0

、しかし、私は残して同意しませんiVars。 OOPの.hファイルは、通常、すべての変数とメソッドを表示するヘッダーファイルです。それは彼らを宣言する。将来このクラスが何をしているかを見たいと思ったら、.hファイルを参照するだけです。あるいは、他の誰かがそのクラスを見る必要があると仮定するか、そのクラスを使ってそのクラスと通信する必要があります。変数を見たり、宣言されているものと、宣言されていないものとを見たりすることが容易になります。つまり、専門的にプログラミングしたいと思っている場合です。

これは本当にあなたがしたいことにかかっています。オブジェクトを作成するのは、後でそのオブジェクトを解放できるからです。だから、あなたはそれを使い続けています。クラス全体のインスタンス変数を1つのメソッドで使用したときにインスタンス変数を作成することは、優れた設計上の決定ではありません。実際には1つのメソッドでのみ使用されている場合、クラス全体が変数を格納しているという意味では貧弱です。この場合、そのメソッド内でそのオブジェクトを作成し、完了したらすぐに解放する必要があります。今、時々

[myText [email protected]"hello"];

作品をやって

。それは実際にあなたのコードに依存します。私は実際に状況の違いを知る唯一の方法は練習だと思います。ラベルを別のオブジェクトに設定してオブジェクトを作成する必要がある場合があります。そうでなければ、それは自動リリースされた等を得ます...

とにかく、基本的には、グローバルに使用される変数にインスタンス変数を使用します。もちろん、UI要素は(クラスやインタフェースビルダー全体で使用されるため)

これが役に立ちます。

+0

私はあなたが質問の最後の部分に取り組んでいるのを見ていますが、私はこの答えが書かれているように誰の混乱も減らすことができません。より簡単な答えは次のようなものです: "与えた例では、中間オブジェクトを作成する必要はなく、定数ストリングを使用すると問題はありません。 " – Caleb

+0

私は、人々があらゆる状況を理解するのを助けることを目指します。また、Obj-C、良いOOPとMVCの設計について話すとき。 – darksky

2

また、クラス内で保護されたiVarまたはプライベートiVarを使用し、そこからプロパティを作成したくない場合があります。 (たとえば、このクラス(プライベート)またはその子孫(プロテクト)のインスタンス以外のものにiVarへのアクセスを許可したくない場合などに使用します。ヘッダーで宣言されたプロパティは、対象オブジェクト。ヘッダー内のivarsを自動的にプロパティとして(中括弧内の宣言の有無にかかわらず)宣言すると、情報隠蔽の観点から悪いことがあります。

.mファイルに実装セクションを追加することもできます。

関連する問題