您的位置:首页 > 大数据 > 人工智能

OC内存分析之retain与copy的简单测试示例

2016-03-18 16:19 302 查看
OC内存分析之retain与copy的简单测试示例

1、初始化Circle类的origin时可以采用以下方式:

(1)origin = [[XYPoint alloc] initWithX:_p.x andY:_p.y];

(2)origin = [_p retain];

或 origin = [_p copy];//此时,XYPoint类需要“遵循”NSCopying协议并实现协议的copyWithZone:方法,以实现深拷贝。

- (id)copyWithZone: (NSZone *)zone

{//拷贝 用已经存在的对象实例化新对象 origin=[_p copy];

XYPoint* temp = [[XYPoint alloc] initWithX:x andY:y];

return temp;

}

(3)self.origin = _p;//等价于[self setOrigin:_p];

内存分析方式取决于setOrigin:内部的实现

.如果声明属性时,赋值方式为 assign,setOrigin:内部的实现如下:

-(void)setOrigin:(XYPoint*)_p

{

origin = _p;

}

.如果声明属性时,赋值方式为 retain,setOrigin:内部的实现如下:

-(void)setOrigin:(XYPoint*)_p

{

if(origin != _p)

{

[origin release];

origin = [_p retain];

}

}

.如果声明属性时,赋值方式为 copy,setOrigin:内部的实现如下:

-(void)setOrigin:(XYPoint*)_p

{

[origin release];

origin = [_p copy];

}

eg:

XYPoint.h

#import <Foundation/Foundation.h>

//类“遵循”协议,那么类中必须要实现协议中的@required方法

//@optional

//copy 消息的接收者所属类需要“遵循”NSCopying协议,并实现协议中的copyWithZone:方法。

@interface XYPoint : NSObject<NSCopying>{

int x;

int y;

}

@property(nonatomic,assign)int x;

@property(nonatomic,assign)int y;

-(id)initWithX:(int)_x andY:(int)_y;

-(NSString*)description;

@end

XYPoint.m

#import "XYPoint.h"

@implementation XYPoint

@synthesize x,y;

-(id)initWithX:(int)_x andY:(int)_y

{

if (self = [super init]) {

x = _x;

y = _y;

}

return self;

}

//对象名.成员函数 [对象 消息];

- (id)copyWithZone:(NSZone *)zone

{//拷贝 用已经存在的对象实例化新对象 origin=[_p copy];

XYPoint* temp = [[XYPoint alloc] initWithX:x andY:y];

return temp;

}

-(NSString*)description

{

return [NSString stringWithFormat%@“(%d,%d)”,x,y];

}

@end

Circle.h

#import <Foundation/Foundation.h>

#import "XYPoint.h"

@interface Circle : NSObject{

int radius;

XYPoint* origin;

}

@property(nonatomic,assign)int radius;

@property(nonatomic,retain)XYPoint* origin;

-(id)initWithR:(int)_r andOrigin:(XYPoint*)_p;

-(NSString*)description;

@end

Circle.m

#import "Circle.h"

@implementation Circle

@synthesize radius,origin;

//

-(id)initWithR:(int)_r andOrigin:(XYPoint*)_p

{

if(self = [super init])

{

radius = _r;

// origin = [[XYPoint alloc] initWithX:_p.x andY:_p.y];//常规做法

// origin = _p;//有没有问题?有 二次删除问题

//origin = [_p retain];//修改之后的语句

origin = [_p copy];//执行过程与内存分析

// self.origin = _p;

// self.origin = [[[XYPoint alloc] init] autorelease];

}

return self;

}

-(NSString*)description

{

return [NSString stringWithFormat%@“r:%d,origin:%@",radius,origin];

}

-(void)dealloc

{//如果类中有对象实例变量,为了避免内存泄漏,可以重写dealloc

[origin release];//nil:空对象 Nil

//向空对象发送消息没有效果

[super dealloc];

}

@end

main.m(测试retain)

#import <Foundation/Foundation.h>

#import "Circle.h"

#import "XYPoint.h"

int main(int argc, const char * argv[])

{

@autoreleasepool {

//个数一致 alloc+retain+copy ==release+autorelease

XYPoint* p = [[XYPoint alloc] initWithX:1 andY:1];//p引用计数为1

Circle* c = [[Circle alloc] initWithR:1 andOrigin:p];//c引用计数为1

//测试retain

XYPoint* p1 = [p retain];//p与p1指向同一块堆空间,并且引用计数会加1 p引用计数为2

NSLog(@"%lu,%lu",[p retainCount],[p1 retainCount]);

[p release];

[c release];

}

return 0;

}

输出结果2,2

main.m(测试copy)

#import <Foundation/Foundation.h>

#import "Circle.h"

#import "XYPoint.h"

int main(int argc, const char * argv[])

{

@autoreleasepool {

XYPoint* p = [[XYPoint alloc] initWithX:1 andY:1];//p引用计数为1

Circle* c = [[Circle alloc] initWithR:1 andOrigin:p];//c引用计数为1

//测试copy

XYPoint* p1 = [p copy];//深拷贝 p与p1引用计数都为1,各自指向一块堆空间

NSLog(@"%lu,%lu",[p retainCount],[p1 retainCount]);

[p release];

[c release];

}

return 0;

}

输出结果为:1,1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: