“和”之间有区别吗;实例变量";及;不动产;在Objective-c中?
Objective-c中的“实例变量”和“属性”之间有区别吗“和”之间有区别吗;实例变量";及;不动产;在Objective-c中?,objective-c,Objective C,Objective-c中的“实例变量”和“属性”之间有区别吗 我对此不是很确定。我认为“属性”是一个具有访问器方法的实例变量,但我可能认为是错误的。属性是一个更抽象的概念。实例变量实际上只是一个存储插槽,就像结构中的插槽一样。通常,其他对象永远不会直接访问它们。另一方面,属性是可以访问的对象的属性(听起来很模糊,应该是这样的)。通常,属性将返回或设置一个实例变量,但它可以使用多个实例变量中的数据,也可以根本不使用。例如: @interface Person : NSObject { NS
我对此不是很确定。我认为“属性”是一个具有访问器方法的实例变量,但我可能认为是错误的。属性是一个更抽象的概念。实例变量实际上只是一个存储插槽,就像结构中的插槽一样。通常,其他对象永远不会直接访问它们。另一方面,属性是可以访问的对象的属性(听起来很模糊,应该是这样的)。通常,属性将返回或设置一个实例变量,但它可以使用多个实例变量中的数据,也可以根本不使用。例如:
@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
(注意:上面的代码是错误的,因为它假设名称已经存在,并且至少有两个组件(例如“比尔·盖茨”而不仅仅是“盖茨”)。我觉得修正这些假设会使代码的实际意义变得不那么清楚,所以我在这里指出它,这样就没有人会天真地重复这些错误。)属性是实现某个值的getter/setter的一种友好方式,具有其他有用的特性和语法。属性可以由实例变量支持,但也可以定义getter/setter来执行更动态的操作,例如,可以在字符串上定义小写属性,动态创建结果,而不是返回某个成员变量的值 下面是一个例子:
// === In your .h ===
@interface MyObject {
NSString *propertyName;
}
// ...
@property (nonatomic, retain) NSString *propertyName;
// === In your .m @implementation ===
@synthesize propertyName /* = otherVarName */;
@property
行定义了类型为NSString*
的名为propertyName
的属性。可以使用以下语法获取/设置:
myObject.propertyName = @"Hello World!";
NSLog("Value: %@", myObject.propertyName);
当您分配或读取myObject.propertyName
时,实际上是在调用对象上的setter/getter方法
@synthesis
行告诉编译器为您生成这些getter/setter,使用与属性同名的成员变量来存储值(或者otherVarName
,如果您在注释中使用语法)
除了@synthesis
之外,您仍然可以通过定义自己的getter/setter来覆盖其中一个getter/setter。这些方法的命名约定是setter的setPropertyName:
,getter的propertyName
(或getPropertyName
,非标准)。另一个仍将为您生成
在@property
行中,您可以在属性的参数中定义一些属性,这些属性可以自动执行线程安全和内存管理等操作。默认情况下,属性是原子的,这意味着编译器将使用适当的锁包装@synthez
ed get/set调用,以防止并发问题。您可以指定非原子
属性来禁用此功能(例如,在iPhone上,您希望将大多数属性默认为非原子
)
有3个属性值控制任何@合成的设置器的内存管理。第一个是retain
,它将自动将release
发送到属性的旧值,并将retain
发送到新值。这是非常有用的
第二个是copy
,它将复制传入的任何值,而不是保留它们。对NSString使用copy
是一种很好的做法,因为调用者可以传入一个NSMutableString,然后从您的下方将其更改出来<代码>复制
将对只有您有权访问的输入进行新的复制
第三个是assign
,它在不调用旧对象或新对象上的retain/release的情况下执行直接指针赋值
最后,您还可以使用readonly
属性来禁用属性的setter。我对接口部分使用属性,其中对象与其他对象接口
实例变量是您在类中需要的东西-除了您之外没有人应该看到和操作它们。默认情况下,readwrite属性将由实例变量支持,实例变量将再次由编译器自动合成
实例变量是存在的变量,在对象的生命周期内保持其值。用于实例变量的内存在首次创建对象时分配(通过alloc),并在解除分配对象时释放
除非另行指定,否则合成的实例变量与属性具有相同的名称,但带有下划线前缀。例如,对于名为firstName的属性,合成的实例变量将被称为_firstName。以前,人们公开使用属性,而IVAR用于私人用途,但几年前,您还可以在@implementation
中定义属性以私下使用它们。但如果可能的话,我仍然会使用IVAR,因为要输入的字母更少,而且根据需要它运行得更快。这是有意义的,因为属性意味着“重”:它们应该从生成的getter/setter或手动编写的getter/setter访问
然而,在苹果最近的代码中,IVAR不再使用。我猜是因为它更像是objc
而不是C/C++
,而且它更容易使用assign
、nullable
等属性。Objective-C属性与实例变量(iVar)
实例变量
@interface SomeClass: NSObject
NSString *someVariable;
@end
财产
@interface SomeClass: NSObject
@property (nonatomic, strong) NSString *someVariable;
@end
属性
在内部使用实例变量
<代码>属性=变量+有界getter/setter
。它是一个具有可变语法和访问权限的方法调用
生成@property
和getter
方法(访问器方法),该方法使用setter
(也称为支持字段),您可以通过下划线支持ivar
使用这些方法(
)\u一些变量
- 由于它调用方法-
机制被使用方法调度
#import "SomeClass.h" @interface SomeClass() @property (nonatomic, strong) NSString *someVariable; @end @implementation SomeClass - (void) foo { //property getter method NSString *a1 = self.someVariable; //NSString *a1 = [self someVariable]; //property setter method self.someVariable = @"set someVariable"; //[self setSomeVariable:@"set someVariable"]; //iVar read NSString *a2 = _someVariable; //iVar write _someVariable = @"set iVar"; } //if you overriding someVariable getter and setter the iVar(_someVariable) is not generated, that is why you can: //1. create some variable explicitly NSString *_someVariable; //or //2. use @synthesize @synthesize someVariable = _someVariable; //overriding - (NSString*) someVariable { return _someVariable; } - (void)setSomeVariable: (NSString*) updatedSomeVariable { _someVariable = updatedSomeVariable; } @end