1.NSString copy retain
NSString copy 方法执行后copyTest和copyTest2内存地址、值、retainCount(值为2)均一样
NSString retain 方法执行后retainTest和retainTest2内存地址、值、retainCount(值为2)均一样
指向的是同一块内存区域(又叫apple弱引用weak reference)
Ios提供了copy和mutablecopy方法,顾名思义,copy就是复制了一个imutable的对象,而mutablecopy就是复制了一个mutable的对象。mutableCopy会重新分配内存地址。
2.自定义对象copy,retain
自定义对象copy需要实现
<NSCopying,NSMutableCopying>协议并重现协议相关方法
//
// Person.h
// ZLD_PropertyTest
//
//说明
//@property (参数) 类型 名字;
//声明property的语法为:@property(属性 [, 属性2, ...]) 类型 名称;
//属性分为3类:
//1.读写属性(Writability)包含:readwrite / readonly
//2.setter语义(Setter Semantics)包含:assign / retain / copy
//3.原子性(Atomicity)包含:nonatomic
//下面具体说明各个属性的含义
//readwrite / readonly:
//决定是否生成set访问器,readwrite是默认属性,生成getter和setter方法;readonly只生成getter方法,不生成setter方法。
//readonly关键字代表setter不会被生成, 所以它不可以和 copy/retain/assign组合使用。
//assign / retain / copy:
//这些属性用于指定set访问器的语义,也就是说,这些属性决定了以何种方式对数据成员赋予新值。
//assign:
//直接赋值,索引计数不改变,适用于简单数据类型,例如:NSIngeter、CGFloat、int、char等。
//retain:
//指针的拷贝,使用的是原来的内存空间。
//对象的索引计数加1。
//此属性只能用于Objective-C对象类型,而不能用于Core Foundation对象。(原因很明显,retain会增加对象的引用计数,而基本数据类型或者Core Foundation对象都没有引用计数)。
//copy:
//对象的拷贝,新申请一块内存空间,并把原始内容复制到那片空间。
//新对象的索引计数为1。
//此属性只对那些实行了NSCopying协议的对象类型有效。
//很多Objective-C中的object最好使用用retain,一些特别的object(例如:string)使用copy。
//
//nonatomic:
//非原子性访问,不加同步,多线程并发访问会提高性能。如果不加此属性,则默认是两个访问方法都为原子型事务访问。默认值是atomic,为原子操作。
#import <Foundation/Foundation.h>
@interface Person : NSObject<NSCopying,NSMutableCopying>
{
int age;
NSString *name;
NSString *sex;
}
@property (nonatomic,assign)int age;
@property (nonatomic,copy) NSString *name;
//@property (nonatomic,copy) NSString *sex;
@property (nonatomic,retain) NSString *sex;
-(Person *) initWith:(int) age andName:(NSString *) name andSex:(NSString *)sex ;//重写实例化方法
//如果在Person头文件中加@property (nonatomic,assign)int age;@property (nonatomic,copy) NSString *name; @property (nonatomic,copy) NSString *sex; 且在Peron的m文件加上@synthesize age ;
//@synthesize name;
//@synthesize sex;
//成员变量age,name,sex的get,set方法不需要在头文件声明且不需在Peron的m文件中实现。
//@property (nonatomic,copy) NSString *name;中的copy用来指定name变量的调用set方法时的以何种方式对数据成员赋予新值 此处相当于用自己重写setName方式对数据成员赋予新值 @property (nonatomic,retain) NSString *name;相当于
//-(void) setName:(NSString *)_name{
//
// if(name!=_name){
// [name release];
// [_name retain];
// name = [[NSString alloc] initWithString: _name];
// }
//}
//@property (nonatomic,assign) NSString *name;相当于
//-(void) setName:(NSString *)_name{
// name = _name;
//}
-(void)setAge:(int) _age;
-(int) getAge;
-(void) setName:(NSString *)_name;
-(NSString *)getName;
-(void) setSex:(NSString *)_sex;
-(NSString *)getSex;
@end
//
// Person.m
// ZLD_PropertyTest
//
#import "Person.h"
@implementation Person
@synthesize age ;
@synthesize name;
@synthesize sex;
-(Person *) initWith:(int) _age andName:(NSString *) _name andSex:(NSString *) _sex {
self = [super init];
if(self){
age = _age;
[self setSex:_sex];
[self setName:_name];
}
return self;
}
-(void)setAge:(int) _age{
age = _age;
}
-(int) getAge{
return age;
}
//重写setName方法
-(void) setName:(NSString *)_name{
NSLog(@"setName %@",_name);
if(name!=_name){
[name release];
name = [_name copy];
}
}
-(NSString *)getName{
NSLog(@"getName");
return name;
}
//重写setSex方法
-(void) setSex:(NSString *)_sex{
NSLog(@"setSex");
if(sex!=_sex){
[sex release];
// sex = [_sex copy];
sex = [_sex retain];
}
}
-(NSString *)getSex{
NSLog(@"getSex");
return sex;
}
- (id)copyWithZone:(NSZone *)zone
{
Person *copy = [[[self class] allocWithZone:zone] init];
copy->name = [name copy];
copy->sex = [sex copy];
// copy->name = [name copyWithZone:zone];;
// copy->imutableStr = [name copyWithZone:zone];//
copy->age = age;
return copy;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
Person *copy = NSCopyObject(self, 0, zone);
copy->name = [self.name mutableCopy];
copy->sex = [self.sex mutableCopy];
copy->age = age;
return copy;
}
//资源释放 先释放自己的 在调用父类的方法释放资源
-(void)dealloc{
NSLog(@"person dealloc ");
[sex release];
[name release];
[super dealloc];
}
@end
Person * person = [[Person alloc]init];
NSString *name = [[NSString alloc]initWithFormat:@"张三"];
NSLog(@"name adress :%p %@ recount %li",name,name, [name retainCount]);
person.name = name;
NSLog(@"name adress :%p %@ recount %li",name,name, [name retainCount]);
NSLog(@"person name adress :%p %@ recount %li",person.name,person.name, [person.name retainCount]);
NSString *sex = [[NSString alloc]initWithFormat:@"男"];
NSLog(@"sex adress :%p %@ recount %li",sex,sex, [sex retainCount]);
person.sex = sex;
NSLog(@"sex adress :%p %@ recount %li",sex,sex, [sex retainCount]);
NSLog(@"person sex adress :%p %@ recount %li",person.sex,person.sex, [person.sex retainCount]);
Person *person2 = [person copy];
NSLog(@"person adress :%p %@ recount %li",person,person, [person retainCount]);
Person *person3 = [person retain];
NSLog(@"person adress :%p %@ recount %li",person,person, [person retainCount]);
[name release];
[sex release];
[person release];
[person release];
2013-01-09 12:10:46.290 ZLD_PropertyTest[1172:403] name adress :0x1038017c0 张三 recount 1
2013-01-09 12:10:46.291 ZLD_PropertyTest[1172:403] setName 张三
2013-01-09 12:10:46.291 ZLD_PropertyTest[1172:403] name adress :0x1038017c0 张三 recount 2
2013-01-09 12:10:46.292 ZLD_PropertyTest[1172:403] person name adress :0x1038017c0 张三 recount 2
2013-01-09 12:10:46.292 ZLD_PropertyTest[1172:403] sex adress :0x100103b40 男 recount 1
2013-01-09 12:10:46.293 ZLD_PropertyTest[1172:403] setSex
2013-01-09 12:10:46.293 ZLD_PropertyTest[1172:403] sex adress :0x100103b40 男 recount 2
2013-01-09 12:10:46.293 ZLD_PropertyTest[1172:403] person sex adress :0x100103b40 男 recount 2
2013-01-09 12:10:46.294 ZLD_PropertyTest[1172:403] person adress :0x1038012e0 <Person: 0x1038012e0> recount 1
2013-01-09 12:10:46.294 ZLD_PropertyTest[1172:403] person2 adress :0x1038019f0 <Person: 0x1038019f0> recount 1
2013-01-09 12:10:46.295 ZLD_PropertyTest[1172:403] person adress :0x1038012e0 <Person: 0x1038012e0> recount 2
2013-01-09 12:10:46.295 ZLD_PropertyTest[1172:403] person3 adress :0x1038012e0 <Person: 0x1038012e0> recount 2
2013-01-09 12:10:46.299 ZLD_PropertyTest[1172:403] person dealloc