@property是一种新的编译器功能,表示声明了一个新对象的属性。这个预编译指定的作用是自动声明属性的setter和getter方法。
@synthesize也是一种新的编译器功能,表示“创建该属性的访问器”,代替getter和setter方法的具体实现。
这两个特性可以让我们少敲点代码
点表达式 obj.a和[obj a]作用一致。
和java中的用对象访问public变量一样。
下面说下具体的例子
// Student.h
#import <Cocoa/Cocoa.h>
@interface Student : NSObject {
NSString *name;
NSString *studentNO;
}
- (NSString*)name;
- (NSString*)studentNO;
- (void)setName:(NSString*)aName;
- (void)setStudentNO:(NSString*)aStudentNO;
@end
// Student.h
- (NSString*)name
{
return name;
}
- (NSString*)studentNO
{
return studentNO;
}
- (void)setName:(NSString*)aName
{
[name autorelease];
name = [aName copy];
}
- (void)setStudentNO:(NSString*)aStudentNO
{
[studentNO autorelease];
studentNO = [aStudentNO copy];
}
//main里面这么用:
Student *hayes = [[Student alloc] init];
[hayes setName:@"Hayes"];
[hayes setStudentNO:@"00000"];
NSLog(@"Name: %@", [hayes name]);
NSLog(@"Student NO: %@", [hayes studentNO]);
下面是用了特性之后
// Student.h
#import <Cocoa/Cocoa.h>
@interface Student : NSObject <NSCoding> {
NSString *name;
NSString *studentNO;
}
@property(copy) NSString *name;
@property(copy) NSString *studentNO;
@end
// Student.m
#import "Student.h"
@implementation Student
@synthesize name;
@synthesize studentNO;
@end
在main函数里可以这么调用:
Student *hayes = [[Student alloc] init];
hayes.name = @"hayes";
hayes.studentNO = @"00001";
NSLog(@"%@", hayes.name);
NSLog(@"%@", hayes. studentNO);
属性声明
属性声明以关键词@property开头。 @property 可以出现在类的 @interface 块中方法声明的任何地方。@property 还可以出现在protocol 或者 category声明中。
@property (attributes) type name;
Property跟Attribute都可翻译为属性,但两者在这里是不同的,Property只类范围的属性,而Attributes是额外属性,作用域比Property小。为避免混淆, 额外属性指代Attribute,如果没有加额外二字,则默认指Property。通过@property(attribute [, attribute2, ...])可以使用带有额外属性的属性。 像方法一样,属性作用域限定在它们的包装借口声明中。属性使用逗号来分隔一系列变量名,属性的额外属性会应用于所有的命名属性。
如果你使用 @synthesize 指令来告诉编译器去创建访问器方法 ,自动生成的代码与所给的关键词是匹配的。如果你自己来实现访问器方法,你应当确保访问器方法与配置相匹配 (例如,要是你指定了 copy ,你就要确保你确实将输入值拷贝到了setter 方法).
下面简单介绍下具体的属性,
readwrite
知名属性属性是 read/write. 默认是这个选项。
getter 跟 setter 方法都要放在 @implementation 块中. 要是你在实现块中使用 @synthesize指令, getter 和 setter 方法则将被集成。
readonly
指明属性是只读的。
如果你指定了 readonly, 那么 @implementation 块中只需要一个getter方法. 要是你在实现块中使用 @synthesize指令, 那么只有 getter 方法会被集成。除此之外,假设你试图使用逗点语法给一个只读属性赋值,编译器将会报错。
strong
指明此属性跟目标对象有着紧密的(拥有)关系。
weak
指明与目标对象是松散的(非拥有)关系。
假如目标对象被释放了,属性值将自动被设为 nil.
( OS X v10.6 和 iOS 4不支持弱属性; 取而代之的是 assign.)
copy
指明对象的副本应当用于赋值操作。
之前的值发送给一个 release 消息.
副本通过调用 copy 方法被创建. 除了对象类型(实现了 NSCopying 协议),对其它类型这个额外属性是无效的。
assign
指明 setter 使用简单赋值。这个额外属性是默认选项。
在标量类型中你会用到这个额外属性,例如 NSInteger 和 CGRect.
retain
指明对象赋值时执行 retain 。
之前的值将发给一个 release 消息。
- -
( void)setName:(NSString*)newName { if (name != newName) { [name release]; name = [newName retain]; // name’s retain count has been bumped up by 1 } - }
nonatomic
指明访问器是非原子的。默认情况下,访问器是原子的。
属性默认是原子的,这种情况下生成的访问器提供了多线程环境下对属性的安全访问/存取互斥互斥,同一时刻,只有一个线程可以访问属性。
对copy 和retain的解释 上面的语言太抽象了 那么请允许我在这里对 copy 和 retain 的区别作详细的介绍
比如一个NSString 对象,地址为0×1111 ,内容为@”STR”
Copy 到另外一个NSString 之后,地址为0×2222 ,内容相同,新的对象retain为1 ,旧有对象没有变化
retain 到另外一个NSString 之后,地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1
retain 是指针拷贝,copy 是内容拷贝