1

重複の可能性:
self.ivar と ivar の違い?

[self setVariable: newStuff]Objective-C では、との違いは何variable = newStuffですか?

変数を持つクラスがある場合

@property (nonatomic) NSInteger num;

変数を変更したい場合、通常は次のことができます

[self setNum: newNum]

しかし、あなたもできる

num = newNum

variable を宣言するとreadOnly、最初のメソッドを使用して変更できないことはわかっていますが、その背後にある概念は何ですか? セッターを持つ2番目のメソッドを独自のクラスの外で呼び出すことができるという理由だけですか? クラスのインスタンスが「サンプル」と呼ばれていた場合と同様です。

[sample setNum: newNum]

しかし、クラス内で変数を変更する場合、どちらの方法でも問題ありませんか?

4

3 に答える 3

2

Objective-C では、[self setVariable: newStuff] と variable = newStuff の違いは何ですか?

厳密に言えば、そのうちの1 つはvariableプロパティに in のnewStuff値を割り当て、もう 1 つnewStuffは iVarvariableに の値を割り当てますが、あなたが念頭に置いていたのは と の比較でし[self setVariable: newStuff]self.variable = newStuff。その場合、何も違いはなく、コンパイラはケース 2 をケース 1 に展開します。

変数 readOnly を宣言すると、最初の方法を使用して変更できないことはわかっていますが、その背後にある概念は何ですか? セッターを持つ2番目のメソッドを独自のクラスの外で呼び出すことができるという理由だけですか? クラスのインスタンスが「サンプル」と呼ばれていた場合と同様です。

readonly変数は、特定のプロパティがクラスの実装に対してプライベートであるが、他のクラスから見える必要がある場合に重要です。

たとえば、スタックを作成している場合、スタック上の項目数のカウントを公開したい場合がありますが、他のクラスがカウント変数に書き込めるようにすることは非常に悪い考えです。私が賢くなく、カウント変数のようなものを使用していた場合、セマフォのカウントを内部的に調整できるようにしたい (つまり、内部的に読み書きできるようにする必要がある) ため、目に見える読み取り専用プロパティを宣言して、他のクラスが取得できますが、内部で読み取り書き込みを宣言して、変更できるようにします。

//.h
@interface CFExampleStack : NSObject 

@property (nonatomic, assign, readonly) int count; //readonly

@end

//.m
@interface CFExampleStack ()

@property (nonatomic, assign) int count; //readwrite

@end
于 2012-12-25T04:38:50.490 に答える
1

もう1つの重要な違い...

KVCを使用するたびに機能し、オブジェクトをバイパスしself.propながらオブジェクトの変化を観察できます。_prop

于 2012-12-25T06:30:20.547 に答える
1

セッターを持つ2番目のメソッドを独自のクラスの外で呼び出すことができるという理由だけですか?

まあ、それはインスタンス変数がどのように宣言されているかによって異なります。デフォルトでは、インスタンス変数は です@protected。つまり、クラスとそのサブクラス内からのみアクセスできます。ただし、 ivar を として明示的に宣言すると@public、C struct ポインター メンバー operator を使用して、クラスの外部にアクセスできます->

obj->publicIvar = 42;

ただし、カプセル化に違反するため、これはお勧めできません。

さらに、カスタム セッター メソッドを使用すると、インスタンスのプロパティが更新されたときにカスタム アクションを実行できます。たとえば、backgroundColora のプロパティを変更する場合UIView、新しいUIColorオブジェクトを適切な ivar に割り当てるだけでなく、それ自体を再描画する必要があります。そのためには、副作用のあるカスタム セッターの実装が必要です。

さらに、オブジェクトを保持するインスタンス変数の場合、保持された (「強い」) プロパティとコピーされたプロパティがあります。整数などのプリミティブ型のセッターを書くのは簡単ですが、

- (void)setFoo:(int)newFoo
{
    _foo = newFoo;
}

対照的に、保持またはコピーされたプロパティには、適切なメモリ管理呼び出しが必要です。

- (void)setBar:(Bar *)newBar
{
    if (_bar != newBar) {
        [_bar release];
        _bar = [newBar retain]; // or copy
    }
}

このような実装がないと、参照カウントが行われないため、割り当てられたオブジェクトが時期尚早に割り当て解除されるか、リークされる可能性があります。

于 2012-12-25T04:37:51.487 に答える