#import <Foundation/Foundation.h>
@interface Demo01 : NSObject{
/**实例变量*/
NSString *string_;
}
/**使用@property让编译器知道我们有一个属性,但是那还不够。
在执行文件中使用@synthesize,我们可以使编译器自动生成获取器(setter)和
提取器(getter)
*/
@property(nonatomic,copy) NSString *string;
@end
属性特性 | 属性定义 |
---|---|
只读/readonly | 当你不希望属性被人修改时。你仍然可以修改字段支持的属性,且编译器不会生成一个安装器。 |
保留/retain | 当你处理对象的值时。编译器将保留传递值,并当有新值来到的时候释放旧值。 |
读写 | 当你想要属性可以被人修改时。编译器将为你生成一个获取器和一个安装器。这是默认情况。 |
复制(copy) | 当你想要保留一些值的复制而不是那个值本身时。例如,如果你想要保留一个数组,并且不希望人们在他们设置后还能够改变它的内容。只要发送一个复制的消息到传递值,然后保留它们。 |
指派(assign) | 当你处理基本类型时。如ints,floats等等,编译器只创建一个安装器,并使用一个简单的语句myField=什么值。这是默认情况,但通常并不是你想要的。 |
下面是Objective-C为每个属性(Property)生成的声明,请你为它们编写代码。假设每个都通过名为_myField的字段被返回(以下是在MRC模式下,ARC会报错)。
@property(nonatomic,readonly) NSString *myField;
//代码
- (NSString *) getMyField{
return _myField;
}
@property(nonatomic,retain) NSString *myField;
//代码
- (NSString *) getMyField{
return _myField;
}
- (void) setMyField:(NSString *)myField{
if (myField != _myField) {
[_myField release];
_myField = [myField retain];
}
}
@property(nonatomic,assign) NSString *myField;
//代码
- (NSString *) getMyField{
return _myField;
}
//在这里要注意——NSString是引用计数对象,
//因此,虽然这在技术上行得通,但是为一个NSString使用一个指派属性,可能并非一个好主意.
//然而,对于如boolean和float这样的基础类型,
//你不能采用引用计数。而指派几乎总是随你所想的。
- (void) setMyField:(NSString *)myField{
self.myField = myField;
}
@property(nonatomic,copy) NSMutableArray *array;
--------
//以下为测试copy属性的代码:
Demo02 *d = [[Demo02 alloc] init];
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:@"23"];
NSLog(@"%@",array);
d.array = array;
[array addObject:@"555"];
NSLog(@"%@",d.array);
NSLog(@"%@",array);
//结果:
array before:(23)
d.array:(23)
array after:(23, 555)
问:(MRC环境下)我怎么才能知道是否有东西保留(retain)了我的对象,如数组或其它什么?
答:基本上,你不用关心这个。按照内存规则,也就是说,如果你从alloc、new、copy、mutableCopy获得的,你必须发送它一个释放(release)。否则,保留(retain)/释放(release)它,如果你想要一会使用。除那以外,让其他类处理它们自己的内存管理。