目标C:哪个改变了,属性还是ivar?

chw*_*hwi 0 iphone objective-c ivar xcode4.2

担心重复,但似乎无法找到和回答我可以在任何其他帖子中理解,我只需要问:

当我在我的.h:

@interface SecondViewController : UIViewController{    
NSString *changeName;    
}

@property (readwrite, retain) NSString *changeName;
Run Code Online (Sandbox Code Playgroud)

然后在我的.m

@synthesize changeName;

-(IBAction)changeButton:(id)sender{
changeName = @"changed";
}
Run Code Online (Sandbox Code Playgroud)

当我按下"changeButton"时,它是合成属性还是实例变量?

Mar*_*rio 7

你(而且似乎其他一些人回答)是属性与实际变量混淆.

属性的工作方式是,它们创建设置或获取/返回ivars的METHODS(称为setter和getter).并且符号(self.string)实际上隐藏了这些方法.所以一个属性不能被改变,只有声明的iVar是.

当你声明一个这样的属性时:

@property (nonatomic, retain) NSString *string;
Run Code Online (Sandbox Code Playgroud)

并且@synthesize它发生以下情况:

现在self.xxxx的作用是,它实际上将消息xxxx发送给self(如[self xxxx]).它适用于任何方法,而不仅仅是属性,尽管它只应与属性一起使用.

所以当你做self.string = @"hello"时,它实际上归结为

[self setString: @"hello"];
Run Code Online (Sandbox Code Playgroud)

(请注意,编译器实际上知道您正在尝试设置,因此发送setString消息而不是仅发送字符串.如果您访问self.string,它将发送[self string])

因此,您不设置属性,您调用本身设置iVar的(合成)setter方法.

如果您知道自己在做什么,可以直接访问iVar.只是打电话

string = @"something else";
Run Code Online (Sandbox Code Playgroud)

将产生泄漏代码,因为没有进行内存管理.合成的访问器和setter实际上是为你做的,具体取决于你如何定义属性(保留,复制,分配).

因为setter(对于保留属性)不仅仅是这样做

IVar = newValue
Run Code Online (Sandbox Code Playgroud)

如果您声明了保留属性,它实际上看起来像这样:

-(void) setString: (NSString*) newString {
  if (string) [string release];
  string = [newString retain];
 }
Run Code Online (Sandbox Code Playgroud)

因此,属性合成需要一些工作.

编辑

因为它似乎仍然不清楚,所声明的属性不应被视为变量.在上面的例子中,使用时

@synthesize string = _string;
Run Code Online (Sandbox Code Playgroud)

没有名为"string"的变量.这就是访问通过setter方法设置iVar _string的方法结构的方式.由于string不是变量/对象指针,因此无法向其发送消息([string doSomething]将无效).当你使用@synthesize字符串合成属性时; 生成的iVar与属性名称相同.然后调用[string doSomething]将起作用,但它与属性无关."字符串"指的是iVar.因此,强制命名iVars的惯例,因此当您打算使用getter/setter时,不要意外地访问iVar.