assign,copy,retain -Object-C中纠结的属性(转)
先看assign 的情况,因为只是默认的方式
@property(nonatomic,assign) NSString *name;
那么编译器会生成,相应的get,set方法,类似如下:
- (NSString *) name{
return name;
}
- (void)setName:(NSString *)theName{
name=theName;
}
可见,get,set 方法,仅仅是将属性指针进行响应的操作。
可见assgin申明的属性:
仅仅是变量指针的赋值和变更。
那么,在使用中,我们要小心了!如果我们在其他地方释放了theName,所指向的内存。那么类中的name指针就会成为野指针,那么调用name的值,就会出错,因为内存已经释放了。
这三个属性,我想用三篇来分别讲述。这样会更加清晰。
------------------------------------------------------------------------------------------------------
这次,要讲的属性为:copy
开始吧,不废话了,还是用代码说话。
-----------------*.h
#import
@interface AddressCard : NSObject{
NSString *name;
NSString *email;
}
// copy 属性,编译器将在setter方法内生成实例变量的副本
@property(nonatomic,copy) NSString *name;
@property(nonatomic,copy) NSString *email;
- (void)setName:(NSString *)theName andEmail:(NSString *)theEmail;
- (void) print;
@end
------------*.m
#import "AddressCard.h"
@implementation AddressCard
@synthesize name;
@synthesize email;
- (void) print{
NSLog(@"=====================");
NSLog(@"name=%s",[name UTF8String]);
NSLog(@"email=%s",[email UTF8String]);
NSLog(@"=====================");
}
- (void)setName:(NSString *)theName andEmail:(NSString *)theEmail{
self.name=theName;
self.email=theEmail;
}
@end
实际使用中:
编译器将为我们生成相应的get,set方法:
get方法:
-(NSString *)name{
return name;
}
set方法:
-(void)setName:(id)newValue{
if (name != newValue) {
[name release];
name = [newValue copy];
}
}
copy属性:
这样,如果我们使用self.name将会执行编译器为我们生成的setName方法。
如果用name,那将直接为变量name进行指针赋值。
这三个属性,我想用三篇来分别讲述。这样会更加清晰。
------------------------------------------------------------------------------------------------------
retain
setter方法对参数进行release旧值,再retain新值,如下代码:
- -(void) setObj:(ClassX*) value
- {
- if (obj != value)
- {
- [obj release];
- obj = [value retain];
- }
- }
------------------------------------------------------------------------------------------------------
@property是一个属性访问声明,扩号内支持以下几个属性:
1,getter=getterName,setter=setterName,设置setter与getter的方法名
2,readwrite,readonly,设置可供访问级别
2,assign,setter方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题
3,retain,setter方法对参数进行release旧值再retain新值,所有实现都是这个顺序(CC上有相关资料)
4,copy,setter方法进行Copy操作,与retain处理流程一样,先旧值release,再Copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。
5,nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级。
retain是指针拷贝,copy是内容拷贝;
如果你不懂怎么使用他们,那么就这样 ->
- 使用assign: 对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float, double, char, 等等)
- 使用copy: 对NSString
- 使用retain: 对其他NSObject和其子类。

浙公网安备 33010602011771号