zoukankan      html  css  js  c++  java
  • IOS开发的内存管理

        关于IOS开发的内存管理的文章已经很多了,因此系统的知识点就不写了,这里我写点平时工作遇到的疑问以及解答做个总结吧,相信也会有人遇到相同的疑问呢,欢迎学习IOS的朋友请加ios技术交流群:190956763,共同学习,共同进步!

        假如在.h文件里,定义一个变量@property (nonatomic,retain) AController  *aController;

        疑问1:创建对象时候,一般会使用alloc,new,copy或者mutalbeCopy等方法,

        哪种写法是正确的?

        A self.aController=[[AController alloc] init];

        B self.aController=[[[AController alloc] init] retain];

        C self.aController=[[[AController alloc] init] autorelease];

        D self->aController=[[AController alloc] init];

        答案:C,D   引用计数的主要接口alloc,allocwithzone,new(带初始化) 为对象分配内存,retainCount为“1”,并返回此实例,而调用self.aController,self本身有干了活,他把_aController这个变量相当于又retain一下,因此A的retaincount已经是2了,已经泄露了!因此不需要B这样retain了,加autorelease的话,就不管retaincount是几了,反正都会释放(不过这地方为什么这样我也有点搞不懂,还求达人解释),如果用D话,没有执行aController的setter方法,因为此时retainCount为“1”,所以D也是正确的,C的话也能用,但是不是好的用法

        疑问2:在dealloc方法中,这么写有问题吗?

    复制代码
    - (void)dealloc{
        [self.aController release];
        self.aController = nil;
        [super dealloc];
    }
    复制代码

        答案:这里不需要release了,因为self.aController = nil;已经调用了release了,当然也可以这么写

    复制代码
    - (void)dealloc{
        [self->aController release];
        self->aController = nil;
        [super dealloc];
    }
    复制代码

    解释:对于set method来说,用synthesize来让系统帮我们生成的set方法和如下的类似:

    复制代码
    - (void)setAbc:(id)newAbc
    {
          if(_abc != newAbc){
               [_abc release];
               _abc = [newAbc retain]; //是retain还是copy取决于你property声明时的attributes  
           }
    }
    复制代码

    如果新值和成员相等,就不需要进行重复的赋值了,不等的话,需要把新值赋给成员,同时,成员_abc原来的内容就不需要了,这里要先调用release进行释放。(这个具体的原因在那本讲Objective-C的书中写的很清楚,请查看)。

    因此在这里,调用self.abc = nil;
    就等于已经调用了[_abc release];  和_abc = nil;

    self.abc = nil;和[_abc release]; 都不一定释放对象,因为该对象还可能被别的引用,这里的操作的意图就是:别的地方用没用_abc我不知道,在这里的_abc我不用了。

    为什么release后还要设置nil呢?因为是这样的,如果引用 计数等于0还对该对象进行操作,则会出现内存访问失败,crash,所以尽量设置为nil,但是单纯设置为nil,如果retaincount不是0的话,内存一样泄露的,因此应该设置nil的时候,先保证变量的retaincount是0了

    疑问3:为什么有些变量不用考虑retain,release呢?

    NSString *str1 = @”constant string”;

    str1retain count是个很大的数字。Objective-C对常量字符串做了特殊处理。

    当然,如果你这样创建NSString,得到的retain count依然为1

    NSString *str2 = [NSString stringWithFormat:@”123”];

    实际上对于 [NSString stringWithFormat:] 这类构造函数返回的对象都是autorelease的,所以也不用考虑retain,release

    疑问4:在ARC的情况下,按说不用自己在考虑release了,为什么还会有dealloc方法存在呢?

    答案:虽然在ARC下,不用考虑release了,但是我们可能还要释放一些其他的东西,比如delegate,关闭定时器,关闭gps定位等,另外如果在ARC下,我们自己不放心,为了安全,自己释放变量也没有什么错误发生!另外不用再调用[super dealloc]了

    比如在ARC下,我们可能会这么写

    复制代码
    - (void)dealloc
    {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
        [self.closeButtonTimer invalidate];
        [self.webView setDelegate:nil];
        [self setLocationDetectionEnabled:NO];
    }
    复制代码

    注意:比如Delegate,如果不在dealloc中释放它,如果页面有多线程的调用,比如开辟个线程从网上down图片子类的,它down下来后需要找这个页面,但是可能用户操作比较快,比如点了后退按钮,这时候页面可能已经销毁了,于是就导致页面崩溃了,所以dealloc中要释放掉delegate

    疑问5:怎么能知道哪里内存泄露了呢?

    这个就不详细解释了,看相关的帖子说的很详细了

    http://www.cocoachina.com/newbie/basic/2012/1204/5242.html

    疑问6:声明为IBOutlet属性的,在MRC中应该retain还是assign?在ARC中应该是strong还是weak?

     在MRC中,应该是retain的,因为IBOutlet本身就是retain的

    任何一个被声明为IBOutlet并且在Interface Builder里被连接到一个UI组件的成员变量,会被额外retain一次。
    常见的情形如

    IBOutlet UILabel *label;

    这个label在Interface Builder里被连接到一个UILabel。此时,这个label的retainCount为2。
    所以,只要使用了IBOutlet变量,一定需要在dealloc或者viewDidUnload里release这个变量。

    在ARC中,property,我们将其申明为weak(事实上,如果没有特别意外,除了最顶层的IBOutlet意外,自己写的outlet都应该是weak)。通过加载xib得到的用户界面,在其从xib文件加载时,就已经是view hierarchy的一部分了,而view hierarchy中的指向都是strong的。因此outlet所指向的UI对象不应当再被hold一次了。将这些outlet写为weak的最显而易见的好处是你就不用再viewDidUnload方法中再将这些outlet设为nil了(否则就算view被摧毁了,但是由于这些UI对象还在被outlet指针指向而无法释放)。

    参考:

    http://www.16kan.com/post/214006.html

    http://www.ityran.com/archives/1234

    疑问7:在ARC在,如果用retain,和用strong有什么区别?

    retain关键字在ARC中是依旧可用的,它在ARC中所扮演的角色和strong完全一样。为了避免迷惑,最好在需要的时候将其写为strong,那样更符合ARC的规则。

     
     
    分类: IOS开发
  • 相关阅读:
    收藏本站
    JS动态生成ID+JS绑定数据
    CSS样式a:link
    C#绑定gridview
    jQuery checkbox 全选、全取消
    JS打开新窗口
    中用图片代替浏览按钮
    给button端添加客户端方法
    jQuery操作 checkbox 的全选、反选 , radio, select 功能
    C#弹出对话框
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3179948.html
Copyright © 2011-2022 走看看