ios内存管理

来源:互联网 发布:苹果软件开发前景 编辑:程序博客网 时间:2024/06/06 12:29

1.  内总管理原则(引用计数)
    IOS的对象都继承于NSObject,   该对象有一个方法:retainCount ,内存引用计数。 

    retain    对象的引用计数+1
    copy      copy 一个对象变成新的对象(新内存地址) 引用计数为1 原来对象计数不变
    release            对象引用计数-1 如果为0释放内存
    autorelease      对象引用计数-1 如果为0不马上释放,最近一个个pool时释放    

内存管理的原则就是最终的引用计数要平衡,
       如果最后引用计数大于0  则会内存泄露
       如果引用 计数等于0还对该对象进行操作,则会出现内存访问失败,crash    所以尽量设置为nil
这两个问题都很严重,所以请一定注意内存释放和不用过后设置为nil
2. autoReleasePool
   每个工程都有一个 main.m 文件: 内容如下:
   int main(int argc, char *argv[]) {
   
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;
}很明显C语言的main 函数: 
NSAutoreleasePool 是用来做autorelease 变量释放的,前面说了, autorelease不会马上释放,当他到了最近的pool release 时会检查reatin count 是不是为0, 为0就释放。 
当我们在一段代码时加入了大量的autorelease变量时,我们应该为这段代码加上Autoreleasepool,其它时候不用,在返回一个对象时常常要返回一个autorelease 对象,因为objectC 对象都是动态内存,没有栈的概念,所以不能像C/C++一样返回一个对象到栈,只能用autorelease对象。
3 view  内存管理
   通常我们编程会用到view,   在view 中的方法:
  viewDidload 
  didReceiveMemoryWarning 
 viewDidUnload 
@property (retain) NSArray *iarrTestMem
        
        viewDidLoad
            init retain is         0
            (alloc)               +1 =1
                                    
        if(memwarning)
               didrecivememwarning  -0 =1
                                               
               didviewunload        -1
                                           =0  
                                  will load  viewDidLoad when next load view
        esle
               dealloc:             -1
                                      =0
    我们来看一个变量的生命周期 
 当view被alloc
     A. 框架会自动调用viewDidLoad, 一般来说在viewDidLoad 中分配变量:,假设为alloc 现在变量的reatin 为 0 +1 = 1;
     
     第一种情况:
      B. 如果这时候view被释放,会调用 dealloc,   这时候我们应该在dealloc里release 这个变量现在为0
     
     第二种情况:
       B. 这时候view被换到下层,如navigation的上级,不可显示状态:如果系统内存吃紧: 系统会发 消息,我们的didrecivememwarning 函数 被调用 ,该函数是提醒我们应该释放一些现在用不上的东西,特别是一些较大的如图片,cache 数据等, 注意如果在这里释放了,代码在用的地方要进行判断,是否需要重新加载
       C. 他会调用didviewunload,这时候我们要注意了,因为他调用了didviewunload,在下次这个view被显示的时候 会再次调用didviewload, 我们在didviewload里分配的娈童就会被分配两次,所以我 们在这里一定要释放didview里分配的变量,不管直接分配的还是间接分配的, 如发消息给其它函数分配的。 那我们在下次分配之前释放一次行不行, 不行,因为这 时候内存吃紧了,你应该多释放内存,不然你的程序可能会被系统kill. 还有虽然对 [xxx release]  对nil 发 release 是没问题的,但逻辑上让人觉得很奇怪,以为在别的地方分配过。 所以这里应该释放内存,如果你是一个属性,用:self.xxx = nil 比较好,他相当于帮你释放了原来的,还把xxx设置为了nil. 如果不是一个属性 :也最好把xxx= nil.  这样比较安全。如果这个view不再被换入,下一步直接调用 dealloc, 这时候你的dealloc里的[xxx release], 如果这里的xxx不为nil你在didviewunload里release 了,就非常危险
        D. 如果这时候view被释放,会调用 dealloc,  这时候我们应该在dealloc里release .

0 0