• 内存管理和@property的属性


    内存管理和@property的属性

     

    目录

    • 对内存管理的理解
    • Objective C内存管理方式
    • 内存的管理

    对象的所有权和内存管理原则

    合理解决内存管理带来的问题

    自动释放池

    • @property的属性
    • ARC自动引用计数

     

    对内存管理的理解

     

    Objective C内存管理方式

    MRC(Manual Reference Counting)手动引用计数——需要程序员手动管理内存

    ARC(Automatic Reference Counting)自动引用计数——由系统自动管理内存(实质为编译预处理器给程序源码适当的位置添加引用计数增加和减少的代码)

    设置方式

    在Build Phase的Compile Sources中对应的文件更改其Compiler Flags

    设置为MRC:-fno-objc-arc

    设置为ARC:-fobjc-arc

     

    内存的管理

    对象的所有权和内存管理原则

    一个对象和一个函数都可以拥有对类对象的管理权,因此对象和函数需要负责类对象的创建和释放

    合理解决内存管理带来的问题(在MRC下,在dealloc上有对拥有对象做释放)

    阶段一

    MyClass *myClass = [[MyClass alloc] init];

    //myClass的行为

    [myClass release];

    阶段二

    -(void)setEngine:(Engine *)newEngine{ engine = newEngine; }

    Car *car = [[Car alloc] init];

    Engine *engine = [[Engine alloc] init];  //1

    [car setEngine:engine];  //1

    [engine release];   //0 致使car对象中的engine指向的对象为空

    阶段三

    对setter的调整:-(void)setEngine:(Engine *)newEngine{ engine = [newEngine retain]; };

    存在问题:

    Engine *engine1 = [Engine new];  //1

    [car setEngine:engine1];  //2

    [engine1 release];  //1

    Engine *engine2 = [Engine new];  //1

    [car setEngine:engine2];  //1

    [car release];  //1 此时engine1没有被释放掉,即car原来指向的对象没有被释放

    阶段三

    继续对setter的调整:-(void)setEngine:(Engine *)newEngine{  [engine release]; engine = [newEngine retain];  }

    存在问题

    Engine *engine = [Engine new];  //1

    Car *car1 = [Car new];

    Car *car2 = [Car new];

    [car1 setEngine: engine];  //2

    [engine release];  //1

    [car2 setEngine:[car1 engine]];  //出错  此时engine的引用计数为0,car1和car2都不能使用其engine属性

    阶段四

    继续对setter的调整:-(void)setEngine:(Engine *)newEngine{  [newEngine retain]; [engine release]; engine = newEngine;  }

    自动释放池

     

    @property的属性

    strong和weak

    assign和retain

    atomic和nonatomic

    与线程安全有关

    read、write、readonly、writeonly、readwrite

    读写操作限制

    copy

     

    ARC自动引用计数

    概述

    ARC是LLVM编译器特性,项目中不再使用retain,release,autorelease,启动ARC之后,编译器会自动在合适的地方插入适当的retain,release,autorelease语句,ARC是编译器特性

    指针保持对象的生命

    ARC规则:只要还有一个变量指向对象,对象就会保持在内存中。当指针指向新值,或者指针不再存在时,相关联的对象就会自动释放。本规则对于实例变量、synthesize属性、本地变量都是适用的。

    @property修饰符

    strong:等同于“retain”,属性成为对象的拥有者,引用计数+1

    weak:属性是weak pointer,当对象释放时会自动设置为nil,记住Outlet应该适用weak,引用计数不变

    unsafe_unretained:等同于之前的“assign”,只有IOS 4才应该适用

    copy:和之前的copy一样,复制一个对象并创建strong关联

    assign:对象不能使用assign,但原始类型(BOOL、int、float)任然可以使用

    运用

    “父-子关系”

    父亲拥有一个儿子的strong指针,但为了阻止所有权回环,儿子需要使用weak指针指向父亲,典型例子:delegate模式,View Controller通过strong指针拥有一个UITableView,Table view的data source和delegate都是weak指针,指向你的View Controller

    问题代码分析

    __weak NSString *str = [[NSString alloc] initWithFormat:...];

    NSLog(@"%@",str);//will output "(null)"

    Xcode警告:assigning retained object to weak variable;object will be released after assignment

    ARC的限制

    ARC只能工作于Objective C对象,如果应用使用了Core Foundation或者malloc()/free(),此时需要自己来管理内存

    虽然ARC帮我们自动管理了内存,但因为strong指针会保持对象的生命,某些情况下你仍然需要手动设置这些指针为nil,否则可能导致应用内存不足

    Xcode的ARC自动迁移

    详细操作参见《IOS 5 ARC完全指南.pdf》

    Blocks和ARC

     

    Singleton与ARC

     

    Autorelease和AutoreleasePool

     

    Cocos2D和Box2D

     

  • 相关阅读:
    基于Spring+SpringMVC实现AOP日志记录功能service注入异常为null的解决办法
    关于SpringBoot项目打包没有把依赖的jar包一起打包的解决办法
    JavaFx项目打包成exe,并集成Jre,使Java项目在任意机器运行
    常用正则表达式
    SqlServer 2005及其以上版本能用的查询数据的行号
    js 中的倒计时功能
    数据库删除重复列
    【转】svn文件清除批处理工具
    JS获取当前页面名称
    sql 去除重复记录
  • 原文地址:https://www.cnblogs.com/IOS-Developer/p/4178095.html
Copyright © 2020-2023  润新知