Objective-c 中的“实例变量”和“属性”之间有区别吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/843632/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a difference between an "instance variable" and a "property" in Objective-c?
提问by Thanks
Is there a difference between an "instance variable" and a "property" in Objective-c?
Objective-c 中的“实例变量”和“属性”之间有区别吗?
I'm not very sure about this. I think that an "property" is an instance variable that has accessor methods, but I might think wrong.
我对此不太确定。我认为“属性”是具有访问器方法的实例变量,但我可能认为错了。
回答by Chuck
A property is a more abstract concept. An instance variable is literally just a storage slot, like a slot in a struct. Normally other objects are never supposed to access them directly. A property, on the other hand, is an attribute of your object that can be accessed (it sounds vague and it's supposed to). Usually a property will return or set an instance variable, but it could use data from several or none at all. For example:
属性是一个更抽象的概念。实例变量实际上只是一个存储槽,就像结构中的槽。通常其他对象永远不应该直接访问它们。另一方面,属性是可以访问的对象的属性(听起来很模糊,但它应该如此)。通常一个属性会返回或设置一个实例变量,但它可以使用来自多个或根本不使用的数据。例如:
@interface Person : NSObject {
NSString *name;
}
@property(copy) NSString *name;
@property(copy) NSString *firstName;
@property(copy) NSString *lastName;
@end
@implementation Person
@synthesize name;
- (NSString *)firstName {
[[name componentsSeparatedByString:@" "] objectAtIndex:0];
}
- (NSString *)lastName {
[[name componentsSeparatedByString:@" "] lastObject];
}
- (NSString *)setFirstName:(NSString *)newName {
NSArray *nameArray = [name componentsSeparatedByString:@" "];
NSArray *newNameArray [[NSArray arrayWithObjects:newName, nil] arrayByAddingObjectsFromArray:[nameArray subarrayWithRange:NSMakeRange(1, [nameArray size]-1)]];
self.name = [newNameArray componentsJoinedByString:@" "];
}
- (NSString *)setLastName:(NSString *)newName {
NSArray *nameArray = [name componentsSeparatedByString:@" "];
NSArray *newNameArray [[nameArray subarrayWithRange:NSMakeRange(0, [nameArray size]-2)] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:newName, nil]];
self.name = [newNameArray componentsJoinedByString:@" "];
}
@end
(Note: The above code is buggy in that it assumes the name already exists and has at least two components (e.g. "Bill Gates" rather than just "Gates"). I felt that fixing those assumptions would make the actual point of the code less clear, so I'm just pointing it out here so nobody innocently repeats those mistakes.)
(注意:上面的代码有问题,因为它假设名称已经存在并且至少有两个组件(例如“Bill Gates”而不仅仅是“Gates”)。我觉得修复这些假设将使代码的实际意义不太清楚,所以我只是在这里指出它,所以没有人会无辜地重复这些错误。)
回答by Mike Weller
A property is a friendly way of implementing a getter/setter for some value, with additional useful features and syntax. A property can be backed by an instance variable, but you can also define the getter/setter to do something a bit more dynamic, e.g. you might define a lowerCase property on a string which dynamically creates the result rather than returning the value of some member variable.
属性是为某些值实现 getter/setter 的一种友好方式,具有额外的有用功能和语法。一个属性可以由一个实例变量支持,但你也可以定义 getter/setter 来做一些更动态的事情,例如你可以在一个字符串上定义一个 lowerCase 属性,它动态地创建结果而不是返回某个成员的值多变的。
Here's an example:
下面是一个例子:
// === In your .h ===
@interface MyObject {
NSString *propertyName;
}
// ...
@property (nonatomic, retain) NSString *propertyName;
// === In your .m @implementation ===
@synthesize propertyName /* = otherVarName */;
The @propertyline defines a property called propertyNameof type NSString *. This can be get/set using the following syntax:
该@property行定义了一个名为propertyNametype的属性NSString *。这可以使用以下语法获取/设置:
myObject.propertyName = @"Hello World!";
NSLog("Value: %@", myObject.propertyName);
When you assign to or read from myObject.propertyNameyou are really calling setter/getter methods on the object.
当您分配给或读取时,myObject.propertyName您实际上是在对象上调用 setter/getter 方法。
The @synthesizeline tells the compiler to generate these getter/setters for you, using the member variable with the same name of the property to store the value (or otherVarNameif you use the syntax in comments).
该@synthesize行告诉编译器为您生成这些 getter/setter,使用具有相同属性名称的成员变量来存储值(或者otherVarName如果您在注释中使用语法)。
Along with @synthesizeyou can still override one of the getter/setters by defining your own. The naming convention for these methods is setPropertyName:for the setter and propertyName(or getPropertyName, not standard) for the getter. The other will still be generated for you.
随着@synthesize你仍然可以定义自己的重载的getter / setter方法之一。这些方法的命名约定适用setPropertyName:于 setter 和propertyName(或getPropertyName,不是标准的)getter。另一个仍会为您生成。
In your @propertyline you can define a number of attributes in parens for the property that can automate things like thread-safety and memory management. By default a property is atomic meaning the compiler will wrap @synthesized get/set calls with appropriate locks to prevent concurrency issues. You can specify the nonatomicattribute to disable this (for example on the iPhone you want to default most properties to nonatomic).
在您的@property行中,您可以在括号中为属性定义许多属性,这些属性可以自动执行线程安全和内存管理等操作。默认情况下,属性是原子的,这意味着编译器将@synthesiz使用适当的锁包装ed get/set 调用以防止并发问题。您可以指定nonatomic属性以禁用此功能(例如,在 iPhone 上您希望将大多数属性默认为nonatomic)。
There are 3 attribute values that control memory management for any @synthesizedsetters. The first is retainwhich will automatically send releaseto old values of the property, and retainto the new values. This is very useful.
有 3 个属性值可以控制任何@synthesizedsetter 的内存管理。第一个是retain将自动发送release到属性的旧值和retain新值。这是非常有用的。
The second is copywhich will make a copy of any values passed in rather than retaining them. It is good practice to use copyfor NSString because a caller could pass in an NSMutableString and change it out from under you. copywill make a new copy of the input which only you have access to.
第二个是copy复制传入的任何值而不是保留它们。使用copyNSString 是一种很好的做法,因为调用者可以传入 NSMutableString 并将其从您的下方更改出来。copy将制作只有您可以访问的输入的新副本。
The third is assignwhich does a straight pointer assign without calling retain/release on the old or new object.
第三种是assign在不调用旧对象或新对象上的保留/释放的情况下执行直接指针分配。
Lastly you can also use the readonlyattribute to disable the setter for the property.
最后,您还可以使用该readonly属性来禁用该属性的 setter。
回答by Jens Busch
I use properties for the interface part - where the object interfaces with other objects and instance variables are stuff that you need inside your class - nobody but you is supposed to see and manipulate those.
我使用接口部分的属性 - 对象与其他对象和实例变量的接口是您在类中需要的东西 - 除了您之外没有人可以看到和操作它们。
回答by jitenagarwal19
By default, a readwrite property will be backed by an instance variable, which will again be synthesized automatically by the compiler.
默认情况下,读写属性将由一个实例变量支持,该变量将再次由编译器自动合成。
An instance variable is a variable that exists and holds its value for the life of the object. The memory used for instance variables is allocated when the object is first created (through alloc), and freed when the object is deallocated.
实例变量是一个存在并在对象的生命周期内保持其值的变量。用于实例变量的内存在对象首次创建时(通过 alloc)分配,并在对象被释放时释放。
Unless you specify otherwise, the synthesized instance variable has the same name as the property, but with an underscore prefix. For a property called firstName, for example, the synthesized instance variable will be called _firstName.
除非另外指定,否则合成的实例变量与属性同名,但带有下划线前缀。例如,对于名为 firstName 的属性,合成的实例变量将称为 _firstName。
回答by superarts.org
Previously people use properties publicly and ivars for private usage, but since several years ago, you can also define properties in @implementationto use them privately. But I'd still use ivars when possible, since there are less letters to type, and it runs faster according to this article. It makes sense since properties are mean to be "heavy": they are supposed to be accessed from either generated getters/setters or the ones manually written.
以前人们将属性公开使用,而 ivars 用于私人使用,但从几年前开始,您还可以定义属性@implementation以私下使用它们。但是如果可能的话,我仍然会使用 ivars,因为要输入的字母更少,而且根据这篇文章它运行得更快。这是有道理的,因为属性意味着“重”:它们应该从生成的 getter/setter 或手动编写的 getter/setter 访问。
However, in recent codes from Apple, ivars are not used anymore. I guess because it's more like objcrather than C/C++, plus it's easier to use properties with assign, nullable, etc.
但是,在 Apple 最近的代码中,不再使用 ivars。我猜是因为它更像objc而不是C/C++,再加上它更容易使用与性能assign,nullable等等。

