六:Accessor方法
这一节主要讲述为什么推荐使用Accessor方法以及如何声明和实现他们,主要也是前面讲过的内容的细化。 使用Accessor方法的好处在于大大提高了类的封装性,使你可以简化一些基本的内存管理的内容
1.声明Accessor方法
声明相当简单,如果你稍微有点基础,就应该很熟悉下面举例的代码:
@property (copy) NSString *firstName;
@property (readonly) NSString *fullName;
@property (retain) NSDate *birthday;
@property NSInteger luckyNumber;
2.实现Accessor方法
首先你需要在实现文件的开头添加类似这样的语句:
@synthesize firstName;
@synthesize fullName;
@synthesize birthday;
@synthesize luckyNumber;
之后如果你什么也不添加了,那么系统用默认的实现方法实现他们。但是如果你想自己写实现方法,有三种方法(此处为了不失原文档的准确性,故直接粘贴如下):
- Getter retains and autoreleases the value before returning it; setter releases the old value and retains (or copies) the new value.
- Getter returns the value; setter autoreleases the old value and retains (or copies) the new value.
- Getter returns the value; setter releases the old value and retains (or copies) the new value
当然有几个例子会加深理解,基于以上三种方式我们各给出一个例子
方式一:
- (NSString*) title {
return [[title retain] autorelease];
}
- (void) setTitle: (NSString*) newTitle {
if (title != newTitle) {
[title release];
title = [newTitle retain]; // Or copy, depending on your needs.
}
}
方式二:
- (NSString*) title {
return title;
}
- (void) setTitle: (NSString*) newTitle {
[title autorelease];
title = [newTitle retain]; // Or copy, depending on your needs.
}
当getter方法比setter更频繁的使用时,方式二比较合适。
方式三:
- (NSString*) title {
return title;
}
- (void) setTitle: (NSString*) newTitle {
if (newTitle != title) {
[title release];
title = [newTitle retain]; // Or copy, depending on your needs.
}
}
当频繁使用getter方法和setter方法时,方式三是很合适的。它也适用于不想延长值的生命周期的那些objects,比如集合类。 方式三缺点在于:更新值时是很快把旧的值给释放掉的,而如果另有一个object有这个旧的值的引用,但没有所有权,此时去引用这个值就要出错了,比如:
NSString *oldTitle = [anObject title]; [anObject setTitle:@”New Title”]; NSLog(@”Old title was: %@”, oldTitle); anObject是oldTitle唯一的拥有者,当anObject更新Title值时,就把oldTitle释放掉了,所以那个Log就要出错了。
3.Value Objects使用Copy
这里首先明确一个概念Value Object,文档中说:A value object is in essence an object-oriented wrapper for a simple data element such as a string, number, or date. The common value classes in Cocoa are NSString, NSDate, and NSNumber.意思就是一些简单数据的封装,以NSString, NSDate, and NSNumber为代表,实际开发也就只需要记住这三个。 对于这类object,推荐使用copy而不是retain,如下:
- (NSString *)name {
return [[name copy] autorelease];
}
- (void)setName:(NSString *)aName {
[name autorelease];
name = [aName copy];
}