0

重複を心配していますが、他の投稿で理解できるものを見つけて答えることができないようです。質問する必要があります。

.h にある場合:

@interface SecondViewController : UIViewController{    
NSString *changeName;    
}

@property (readwrite, retain) NSString *changeName;

それから私の.mで

@synthesize changeName;

-(IBAction)changeButton:(id)sender{
changeName = @"changed";
}

「changeButton」を押すと変更されるのは、合成されたプロパティですか、それともインスタンス変数ですか?

4

3 に答える 3

7

あなた(そして答えた他の人のようです)は、プロパティと実際の変数を混同しています。

プロパティが機能する方法は、ivar を設定または取得/返すメソッド (setter および getter と呼ばれる) を作成することです。そして do 記法 (self.string) は実際にこれらのメソッドを呼び出します。したがって、プロパティを変更することはできません。宣言された iVar のみが変更されます。

次のようにプロパティを宣言すると:

@property (nonatomic, retain) NSString *string;

@synthesize すると、次のことが起こります。

  • string という名前の iVar (タイプ NString*) が作成されます

    (もしあなたがそうするなら

    @synthesize string = whateverYouWant
    

    作成された iVar は、whateverYouWant と呼ばれます - 規則では、前にアンダースコア (_string) を付けたプロパティと同じ名前を iVar に付けます)

  • アクセサーメソッドはこのように作成されます

    -(NSString*) string;
    
  • セッターはこのように作成されます

    -(void) setString: (NSString*) newString;
    

ここで、self.xxxx が行うことは、実際にメッセージ xxxx を自分自身に送信することです ([self xxxx] のように)。プロパティでのみ使用する必要がありますが、プロパティだけでなく、任意のメソッドで機能します。

したがって、 self.string = @"hello" を実行すると、実際には次のようになります

[self setString: @"hello"];

(コンパイラは実際に設定しようとしていることを認識しているため、単なる文字列ではなく setString メッセージが送信されることに注意してください。self.string にアクセスすると、[self string] が送信されます)

したがって、プロパティを設定するのではなく、それ自体で iVar を設定する (合成された) セッター メソッドを呼び出します。

何をしているのか分かっていれば、iVar に直接アクセスしても問題ありません。通話中

string = @"something else";

メモリ管理が行われないため、リーク コードが生成されます。プロパティ (retain、copy、assign) の定義方法に応じて、合成されたアクセサーとセッターが実際にこれを行います。

(保持されたプロパティの)セッターは単に行うわけではないため

IVar = newValue

保持されたプロパティを宣言した場合、実際には次のようになります。

-(void) setString: (NSString*) newString {
  if (string) [string release];
  string = [newString retain];
 }

そのため、プロパティの合成には少し手間がかかります。

編集

まだはっきりしていないように見えるので、宣言されたプロパティは変数のように考えるべきではありません。上記の例では、

@synthesize string = _string;

「文字列」と呼ばれる変数はありません。これは、setter メソッドを介して iVar _string を設定するメソッド構造にアクセスする方法です。string は変数/オブジェクト ポインターではないため、メッセージを送信することはできません ([string doSomething] は機能しません)。@synthesize 文字列を使用してプロパティを合成するだけの場合。生成された iVar はプロパティと同じ名前になります。[string doSomething] の呼び出しは機能しますが、プロパティとは関係ありません。「文字列」は iVar を指します。したがって、iVar にアンダースコアを付けた名前を付ける規則により、getter/setter を使用するつもりだったときに誤って iVar にアクセスすることはありません。

于 2012-06-08T10:11:39.097 に答える
2

さて、var

それは常に変数です

あなたの場合、プロパティメソッドはまったく使用されていません。

ここで、次のケースを検討してください。

self.changeName = @"changed";

このようにプロパティを使用していますが、これは、コンパイラによって「魔法のように」作成されたメソッド、setter メソッドと getter メソッドを使用していることを意味し、ここでも var (プロパティは存在しません。実際には、これは setter メソッドと getter メソッドを作成する方法にすぎません)

于 2012-06-08T10:04:39.203 に答える
2

両方。プロパティはインスタンス変数をストレージとして使用します。コードでインスタンス変数を変更しますが、( 経由でself.changeName) プロパティにアクセスすると、インスタンス変数と同じ値が得られます。

通常、ivar とプロパティを区別するために、人々は_ivar の接頭辞を使用します。次に、次のようなプロパティを合成します。

@synthesize myProperty=_myProperty;
于 2012-06-08T10:03:55.980 に答える