zoukankan      html  css  js  c++  java
  • OC内存管理(二)

    一:autorelease

    1> autorelease原理:将我们创建的对象放到一个对象释放池中(是一个栈区)当池子释放时,会将池子中的对象都做一次release操作(自动释放池存放在一个池子中,就近原则,符合先进后出)

    2>自动释放池的创建方式

    (1)ios 5.0以前的创建方式

    NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];

    `````````````````

    [pool  release];//[pool drain];用于mac 

    (2)Ios5.0以后

    @autoreleasepool

    {//开始代表创建自动释放池

    ·······

    }//结束代表销毁自动释放池

    3,类调用类方法中,没有看到引用计数器减一的问题

     例如 NSString *s = [NSString stringWithFormat:@“%d”, 10];这个代码中不需要我们手动释放内存,因为在stringWithFormat:方法内部已经完成了引用计数器减1的操作

    代码:

    好处:不用我们自己管理对象释放的时间
    坏处:  不能灵活的释放我们需要释放对象,如果对象的占用的内存大的话,不要使用autorelease。
    代码示例:
    Person类 
    #import "Person.h"
    #import <Foundation/Foundation.h>
    /**
     *  @class
     注意:继承关系中子类头文件不能用@class
     因为子类要继承父类中的所有属性
     */
    @interface Person : NSObject
    
    @property (nonatomic, retain) NSString *name;
    @property (nonatomic, assign) int age;
    
    - (instancetype)initWithName:(NSString *)name andAge:(int)age;
    + (instancetype)personWithName:(NSString *)name andAge:(int)age;
    
    @end
    @implementation Person
    
    - (instancetype)initWithName:(NSString *)name andAge:(int)age
    {
        if (self == [super init]) {
            
            self.name = name;
            self.age = age;
        }
        return self;
    }
    
    // 注意:也就是在类调用类方法中,alloc中引用计数器加1,因此需要手动释放,当时我们不能在下面调用release
    //      因为刚创建的对象我们就释放,毫无意义,因此我们将它加入到释放池中。由池子来释放
    + (instancetype)personWithName:(NSString *)name andAge:(int)age
    {
        /* 用self调用的原因:
            我们为什么不用类名来调用alloc,因为person子类会继承这个方法,如果用Person的话,子类调用会创建父类的对象
         */
        return [[[self alloc] initWithName:name andAge:age] autorelease];
    }
    
    - (void)dealloc
    {
        self.name = nil;
        NSLog(@"Person ------dealloc");
        [super dealloc];
    }
    
    @end

    Student类继承Person

    #import "Student.h"
    #import "Person.h"
    
    @interface Student : Person
    
    
    @end
    @implementation Student
    
    -(void)dealloc
    {
        NSLog(@"Student------dealloc");
        [super dealloc];
    }
    
    @end

    main函数中

    #import <Foundation/Foundation.h>
    #import "Person.h"
    #import "Student.h"
    int main(int argc, const char * argv[])
    {
        // 按道理说我们在ARC中创建对象的代码必须写在释放池中,因为编译器会将代码加到释放池中
        @autoreleasepool {
        
            Person *p = [Person personWithName:@"zhangsan" andAge:10];
            Student *s = [Student personWithName:@"lisi" andAge:20];
        }
        
        return 0;
    }
              
    二:ARC内存管理机制 (是编译器的特性,手动写的内存管理代码,编译器帮我们完成,不需要我们再去关心)
      1> ARC判断准则:只要没有强指针指向对象,对象就会被释放
      2> 指针的分类
           默认情况下,所有的指针都是强指针,用关键字_strong修饰
           当用__week关键字修饰的指针为弱指针。
          _ _weak Person *p=[[Person alloc]  init];//不合理,对象一创建出来就       被释放掉,对象释放掉后,ARC把指针自动清零。
      3> 特点:默认ARC中不允许调用retain、release、autorelease、retain count,但可以重写dealloc方法,不过该方法中不能写【super  dealloc],因为
    编译器编译时已经帮我们完成了。
           @property的参数:

         Strong:相当于原来的retain(适用于OC对象类型),成员变量是强指针

        Weak:相当于原来的assign,(适用于oc对象类型),成员变量是弱指针

        Assign:适用于非OC对象类型(基础类型)

    ARC也存在循环引用的问题:造成循环引用的原因,dealloc中无法调用,在dealloc中强指针引用的对象无法释放。

    解决的办法:1>头文件中文件包含@class

                       2,property中的修饰符一端strong,一端week,dealloc中不要我们关心,编译器已经帮我们弄好。

    4,将MRC代码转换成ARC代码怎么转换

      步骤:1点击Xcode的 Edit 

               2,选择Edit中的Refactor

               3,选择refactor中的convert to Object-c ARC就可以

      将ARC转回MRC

       步骤:1点击File文件中的Restore snaipshot就可以

    5,OC中的集合的内存管理细节

    • 集合的内存管理细节

    • 1> 当把⼀一个对象添加到集合中时,这个对象会做 了⼀一次retain操作,计数器会+1

    • 2> 当⼀一个集合被销毁时,会对集合⾥里⾯面的所有对 象做⼀一次release操作,计数器会-1

    • 3> 当⼀一个对象从集合中移除时,这个对象会⼀一 次release操作,计数器会-1 

  • 相关阅读:
    Git 学习
    js模块化编程之彻底弄懂CommonJS和AMD/CMD!
    浅析JS中的模块规范(CommonJS,AMD,CMD)
    js实现获取两个日期之间所有日期最简单的方法
    jQuery 中 attr() 和 prop() 方法的区别
    判断某个元素是否在数组的对象中存在
    获取两个数组中不同的元素
    Web前端的缓存机制(那些以代价换来的效率)
    前端技术栈(概览)
    使用layer 弹出对话框 子父页面相互参数传递 父页面获取子页面参数实例
  • 原文地址:https://www.cnblogs.com/-boy/p/4088221.html
Copyright © 2011-2022 走看看