zoukankan      html  css  js  c++  java
  • objectiveC引用计数的使用心得

    Objective-C有不只一种内存管理方式,我这里只讨论引用计数相关内容。

    1. 在堆上分配对象
    所有对象(不知道有无例外)都用堆方式分配内存,也就像c++中的new,对象引用都使用指针啦,很统一。
    2. 指针赋值
    将一个对象直接赋值给另一个,都是赋值指针,若不做特殊操作,人家释放掉后,你就惨了,野指针。后面重点讨论“特殊操作”
    3. copy方法
    obj1 = [obj2 copy];如此使用后,系统为obj1新申请一块内存,拷贝了obj2的内容,以后个不相关了。
    4. 引用计数
    每个对象有一个引用计数,当引用计数为0时,对象自动销毁,如下几个操作可以改变引用计数。
    a,创造对象,引用计数默认为1
    b,向对象传retain消息,引用计数+1
    c,向对象传release消息,引用计数-1
    d,向对象传autorelease消息,将来某个时候应用计数-1
    所有引用计数增加和减少必须配对,谁加谁就负责减,权责明确。若增加多了,会造成内存泄漏,若减少多了,指针就野啦,将来某时刻就得崩溃。
    5. return对象
    c++中经典错误是在return在某函数中栈式分配的一个对象地址,函数返回后该对象地址失效,将来某一时刻被其它数据覆盖。若在对上分配对象,使用者很可能忘记释放,造成内存泄漏。
    objC的习惯是堆分配,autorelease,然后返回,这样基本万无一失。
    Class2 * obj1 = [[Class1 alloc] init];
    [obj1 autorelease];
    return obj1;
    6. 何时需要释放
    a,向某对象发retain消息了
    b,调用alloc,copy和new返回的对象
    记住,b是惯例,其它方法内部都会autorelease一下,别没事不按套路出牌,自己写个另类方法,不autorelease。
    7. 如何使用对象
    a,只用一下,用完不管,跟c传指针一样
    b,需要长时间引用,拿到一个对象后,若需要保存一段时间,可以retain一下,防止这个对象被释放,但可以被别人修改。
    c,copy一下,直接新做了一个,与之前的毫无关系,这样既不会被别人释放,也不会被别人修改
    d,创造一个对象,用init或者new
    a类不需要release,其他都需要release一下
    8,关于属性
    声明属性时可以加上retain关键字,例如@property(nonatomic, retain),这样属性默认实现方式是release原对象,retain形参对象,然后复制给成员对象,如下所示。
    setValue:(class1)obj1
    {
    if(obj != obj1)
    {
    [obj release];
    [obj1 retain];
    obj = obj1;
    }
    }
    在类方法中直接使用成员变量名时代表该变量,前面加self.时调用的是属性,这是有区别的
    比如self.obj = nil;就会将obj release一下,然后赋值nil,而obj=nil;则直接赋值nil,内存泄漏了。
    ---分割线-----------------------------------------------------------
    最后说说使用感受
    如果讲申请和释放资源问题看作一个决策问题的话,那么objc的引用计数方式将全局决策局部化,将求全局最优解转成求局部最优解问题。
     
    c++中new和delete方式,只有一次分配,一次释放。优点是分配释放次数少,不忘记就不会泄漏,虽然不如smartpoint和垃圾回收方便,但在该方面也不会比objC的引用计数差。
    new和delete的问题是合适delete。因为必须确定大家都不用时才能delete,这个机会不好把握,很容易出错,到处野指针。而ObjC繁琐的引用计数机制正好可以克服该缺点,老子的事老子负责,别人我不管,我用了我就retain,我不用我就release,逻辑清晰,使用方便。
    这仅是我一点粗浅的认识,引用计数这种先进技术的优点需要日后慢慢体会。
  • 相关阅读:
    Metasploit基本命令
    Metasploit体系框架与技术模块
    Linux之grep、egrep、fgrep
    python基础-函数详解
    windows用户管理与服务器远程管理
    python基础-三分钟彻底搞懂 集合
    linux之bash特性及脚本编程基础
    location.reload(); 刷新页面 javascript:void(0)禁止点击 read.onload=function ()等待函数完成执行 { $('#img-file').attr('src', read.result) 修改图片属性
    auth模块进行验证登录,forms进行输入和后台进行渲染,novalidate前台不验证
    跨域问题,ajax上传下载文件,cookie实现登录验证,session实现登录验证,
  • 原文地址:https://www.cnblogs.com/rollrock/p/2543973.html
Copyright © 2011-2022 走看看