web-dev-qa-db-ja.com

Objective Cのゲッターとセッターについて説明してください

可能性のある複製:
Setters and Getters(Noobie)-iPhone SDK

私はここの初心者です。過去2か月間iOSの学習を始めたばかりで、プログラミングの経験はありません。 (Javaの小さなビット)。ObjectiveCのゲッターとセッターとは何ですか?それらの使用は何ですか?なぜ@property@synthesizeを使用するのですか?

27
GenieWanted

Getterは、プロパティ(_@property_で宣言)にアクセスする(値を読み取る)たびに呼び出されるメソッドです。そのメソッドが返すものは何でも、そのプロパティの値と見なされます。

_@property int someNumber;
_

...

_- (int)someNumber {
    return 42;
}
_

...

_NSLog("value = %d", anObject.someNumber); // prints "value = 42"
_

Setterは、プロパティ値が変更されるたびに呼び出されるメソッドです。

_- (void)setSomeNumber: (int)newValue { // By naming convention, setter for `someValue` should 
                                    // be called `setSomeValue`. This is important!
    NSLog("someValue has been assigned a new value: %d", newValue);
}
_

...

_anObject.someNumber = 19; // prints "someValue has been assigned a new value: 19"
_

通常、ゲッターから同じ値を返し、セッターに新しい値を出力することはあまり意味がありません。実際に何かを保存するには、クラスでインスタンス変数(ivar)を宣言する必要があります。

_@interface SomeClass : NSObject {
    int _someNumber;
}
_

アクセサ(ゲッターとセッターの総称)を作成して、その値を保存/取得します。

_- (int)someNumber {
    return _someNumber;
}

- (void)setSomeNumber:(int)newValue {
    _someNumber = newValue;
}
_

...

_SomeClass *anObject = [[SomeClass alloc]init];
anObject.someNumber = 15;
NSLog(@"It's %d", anObject.someNumber); // prints "It's 15"
_

さて、プロパティは通常の変数と同じように動作します。すべてのコードを書く意味は何ですか?

まず、これから、アクセサに追加のコードを追加できます。これは、プロパティがアクセスまたは変更されるたびに実行されます。それにはいくつかの理由があります。たとえば、ある種の隠された計算をしたい、オブジェクトの状態を更新したり、キャッシュしたりしたいなどです。

次に、CocoaにはKey-Value Coding(KVC)およびKey-Value Observing(KVO)と呼ばれるクールなメカニズムがあります。プロパティに依存します。開発者ライブラリでそれらについて読むことができます: KVCプログラミングガイド および KVOプログラミングガイド 。ただし、これらは高度なトピックです。

最後に、Objective Cでは、オブジェクトの静的な割り当てはありません。すべてのオブジェクトは動的に割り当てられます( reason )。 (プロパティではなく)インスタンス変数にオブジェクトポインターを保持する場合は、ivarに新しい値を割り当てるたびにすべてのメモリ管理を手動で行う必要があります( 自動参照カウント の場合はtrueではありません)オン)。プロパティを使用すると、メモリ管理コードをアクセサに配置して、生活を楽にすることができます。

この説明は、Objective Cのメモリ管理に精通していない人にはあまり意味がないと思うので、実際のドキュメント/チュートリアルを読むか、すべてを学習するまで(インスタンス変数の代わりに)プロパティを使用してください。何らかの方法で詳細に説明します。個人的には、2番目のオプションは好きではありませんが、それはあなた次第です。

_@synthesize_を使用して、コンパイラーに基本的なアクセサーと基になるインスタンス変数を自動的に生成させることができます。上記のコード(-(int)someNumberおよび-(void)setSomeNumber:)の代わりに、次のように書くことができます。

_@synthesize someNumber = _someNumber; // = _someNumbers tells compiler 
                                      // to name the instance variable `_someNumber`. 
                                      // You could replace it with = `_somethingElse`, of
                                      // course, but that's an ill idea.
_

この1行で_int _someNumber_変数、someNumber getterおよびsetSomeNumber setterが生成されます。アクセサに、インスタンス変数から値を格納/取得するだけでなく、より複雑なことをさせたい場合は、自分で記述する必要があります。

これがすべて理にかなっていることを願っています。

80
zrslv

「ゲッター」および「セッター」は、変数(フィールド)への変更を制御するために使用されます。

「セッター」は、カプセル化の原則に従って、オブジェクト指向プログラミングで最もよく使用されます。この原則によれば、クラスのメンバー変数は、他のコードからそれらを隠して保護するためにプライベートにされ、パブリックメンバー関数によってのみ変更できます。プライベートメンバー変数。

多くの場合、「セッター」には「ゲッター」(アクセサーとも呼ばれます)が付随し、プライベートメンバー変数の値を返します。

Getter/Setterメソッドは、非オブジェクト指向環境でも使用できます。この場合、変更される変数への参照は、新しい値とともにメソッドに渡されます。このシナリオでは、コンパイラーはコードがゲッター/セッターメソッドをバイパスして変数を直接変更することを制限できません。開発者の責任は、変数がこれらのメソッドを介してのみ変更され、直接変更されないことを保証することです。

それらをサポートするプログラミング言語では、プロパティはカプセル化のユーティリティを放棄することなく、便利な代替手段を提供します。

5
user1368198

ほとんどのオブジェクト指向言語のプロパティ「getter」および「setter」は、クラスのインスタンスのプライベートメンバーの周りに「外部」またはユーザーインターフェイスを提供します。一部のOO批評家はそれらを「シンタックスシュガー」と呼びますが、最終的には、クラスのコンシューマーはこれらのインターフェイスを使用し、yoむしろプログラムで制御します実際のプライベートメンバー自体にアクセスするよりも、この方法で、たとえば、プライベート変数が無効な値や範囲外の値を受け取らないように保護したり、プロパティを読み取り専用にしたりできます。さらに興味深いのは、ゲッターとセッターがクラスでネイティブに保持されていないプロパティをラップするかもしれないが、他のインスタンスメンバーに基づいて計算されるかもしれないという考えです。

ゲッターとセッターは確実にObjective-Cに固有のものではありません。他のOO言語でプログラミングを続けると、C#、Javaなどでそれらのフレーバーが見つかります。

がんばろう。

3
David W