Objective-C基础教程七

时间:2022-09-07 08:26:38

@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跟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 消息。

  1. (void)setName:(NSString *)newName {
  2. if (name != newName) {
  3. [name release];
  4. name [newName retain];
  5. // name’s retain count has been bumped up by 1
  6. }

nonatomic
指明访问器是非原子的。默认情况下,访问器是原子的。
属性默认是原子的,这种情况下生成的访问器提供了多线程环境下对属性的安全访问/存取互斥互斥,同一时刻,只有一个线程可以访问属性。


对copy 和retain的解释 上面的语言太抽象了 那么请允许我在这里对 copy 和 retain 的区别作详细的介绍
比如一个NSString 对象,地址为0×1111 ,内容为@”STR”
Copy 到另外一个NSString 之后,地址为0×2222 ,内容相同,新的对象retain为1 ,旧有对象没有变化
retain 到另外一个NSString 之后,地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1
retain 是指针拷贝,copy 是内容拷贝 



参考:http://blog.csdn.net/micheal_j/article/details/7628362

http://blog.csdn.net/ligltc/article/details/6613095