zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    谷歌翻译插件
    WordPress资料收集,以后整理
    WordPress不同分类使用不同的文章模板
    禁用/移除WordPress页面的评论功能
    wordpress设置一个特定的页面作为首页
    wordpress主题之后台菜单编辑,小工具
    tinkcmf视频上传大小限制
    转:解决Onethink上传视频的问题 超棒的解决方案
    linux(centos) 下安装phpstudy 如何命令行进入mysql
    在 Mac OS X 10.9 搭建 Python3 科学计算环境
  • 原文地址:https://www.cnblogs.com/about-zj-blog/p/5292570.html
Copyright © 2011-2022 走看看