首先,你不是在声明一个变量,而是在声明一个属性。属性由实例变量支持,但也添加了方法。这里解释一下放置变量的位置:
@interface MyClass : NSObject {
NSInteger i ;
}
@end
这是在类中放置实例变量的位置。它只能被类和分类中的方法访问。
(旁注:它可以被外部访问,但这不是推荐的做法)
另一个例子:
@interface MyClass : NSObject
@end
@implementation MyClass {
NSInteger i ;
}
@end
这也是实例变量,但只能被编写在该代码块内的方法所访问。(顺便说一下:可以通过查看类定义来访问它,但这不是推荐(或常见)的做法)
另一个例子:
@interface MyClass : NSObject
@property NSInteger i ;
@end
与下面的代码等价:
@interface MyClass : NSObject {
NSInteger _i ;
}
- (NSInteger) i ;
- (void) setI:(NSInteger)value ;
@end
这是一个允许人们获取和设置的属性。您可以在自己的方法或其他方法中使用该变量,例如:
NSLog ( @"The value is %i" , self.i ) ; // if it's your instance method
NSLog ( @"The value is %i" , object.i ) ; // if it's object's instance method
另一个例子:
@interface MyClass : NSObject {
NSInteger i ;
}
@property NSInteger i ;
@end
@implementation MyClass
@synthesize i ;
@end
等同于:
@interface MyClass : NSObject {
NSInteger i ;
}
- (NSInteger) i ;
- (void) setI:(NSInteger)value ;
@end
在这里,您可以使用getter/setter方法或实例变量本身。但是,通常应该使用方法,因为您已[隐式地]将它们声明为原子的,因此它们具有线程同步功能。如果你想让它不做线程处理(并且加快速度,只要不在多线程环境中使用):
@property (nonatomic) NSInteger i ;
@property (nonatomic,readonly) NSInteger i ; // only makes a getter method
我建议你在一段时间内避免使用这个,而是直接使用属性,因为这样可以帮助你避免很多常见的错误。除非你对程序进行了剖析,并确定这是导致性能损失的原因,否则你应该只使用属性。
另一个例子:
@interface MyClass : NSObject
@end
@implementation MyClass
NSInteger i ;
@end
这不是实例变量,而是一个全局变量,恰巧在你的@implementation
作用域中编写。
如上所述,如何将其转换为实例变量(即将其放入括号中)。
还有一点需要注意:
声明属性的方式如下:
@interface MyClass ()
@property NSInteger i ;
@end
这并没有使其变成私有属性。然而,它被隐藏在一些普通人无法访问的文件中,所以编译器并不知道该属性的存在。
你代码中的其他函数仍然可以调用:
[yourObject i] ;
要获取该属性的值,但首先他们必须知道它存在。
附加说明以回答评论中的问题:
默认情况下,属性是原子性的。它不一定遵循原子性的严格定义(我建议您现在不要看这个),但具有相同的效果:线程保证能够看到完整和最新的值,无论另一个线程何时写入它。通常在合成getter/setter方法时实现这一点。
- (NSInteger) i {
@synchronized(self) {
return i ;
}
}
- (void) setI:(NSInteger)value {
@synchronized(self) {
i = value ;
}
}
如果您指定
nonatomic
,它将合成以下内容:
- (NSInteger) i {
return i ;
}
- (void) setI:(NSInteger)value {
i = value ;
}
如果您的属性是
atomic
,那么您不应该直接访问实例变量。这样做会违反您最初为其提供的线程保护。
(附注:有些情况下可以这样做,但在尝试之前请等待您更熟悉线程/同步。)
@interface
中声明的NSInteger
是一个全局变量。它仅仅是一个变量,没有任何属性(访问器方法、KVC等)所具有的特性。 - Rob