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

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

原文地址:https://www.cnblogs.com/about-zj-blog/p/5292570.html