iOS与OSX多线程和内存管理-ARC

Posted by Chen on September 7, 2016

ARC

1.1 内存管理的思考方式

  • 自己生成的对象自己所持有
  • 非自己生成的对象,自己也能持有
  • 自己持有的对象不再需要时释放
  • 非自己持有的对象无法释放

1.2 所有权修饰符

  • __strong修饰符(默认)
  • __weak修饰符
  • __unsafe_unretained修饰符
  • __autoreleaseing修饰符

1.2.1__strong 强引用

** __strong修饰符是id类型和对象类型默认的所有权修饰符.**

附有__strong修饰符的变量obj在超出其变量作用域时, 即在该变量被废弃时,会释放其被赋予的对象

ARC下利用__strong不必再次键入retain或者release

1.2.2__weak 弱引用

虽然__strong已经佷好用了,但是在循环引用问题上 却不行了

循环引用(互相引用–自身引用)会发生严重的内存泄漏

弱引用不能持有对象 __weak在对象被废弃后会自动nil

虽然__weak修饰符是为了避免循环引用的但在访问附有__weak修饰符的变量时,实际上必定访问注册到autoreleasepool的对象

1.2.3__unsafe_unretained

__unsafe_undertained修饰符正如其名unsafe,是不安全的,iOS5以前因为还没有__weak都是它代替的

尽管ARC式的内存管理是编译器的工作,但__unsafe_unretained修饰符的变量不属于编译器的内存管理对象

!__unsafe_undertained引用的对象在使用时要确保其存在

1.2.4__autoreleasing

ARC下不能使用autorelease方法, 但是autorelease功能是起作用的

ARC下通过 –__autoreleasing修饰符的变量来替代调用autorelease方法对象赋值给附有 __autoreleasing修饰符的变量等价于ARC无效时调用对象的autorelease方法,即对象被注册到autoreleasepool中

**但是,显示的添加__autoreleasing修饰符同显示式的添加__strong一样罕见 **

__ 为什么?_

因为 编译器会检查方法名是否以alloc/new/copy/mutableCopy开始,如果不是则自动将返回值的对象注册到autoreleasepoolinit方法返回的对象不注册到autoreleasepool

显示__autoreleasepool例子

  • 访问附有__weak修饰符的变量时,实际上必须访问注册到autoreleasepool的对象
  • id的指针或对象的指针在没有显式指定时会附上__autoreleaseing修饰符
    NSError**error is NSError* __autoreleaseing *error
    

    对象指针

赋值给对象指针时,所有权修饰符必须一致 权修饰符

规则ARC有效

  • 不能使用retain/release/retainCount/autorelease
  • 不能使用NSAllocateObject/NSDeallocateObject
  • 须遵守内存管理方法命名规则
  • 不要显式调用dealloc
  • 使用@autoreleasepool块替代NSAutoreleasePool
  • 不能使用区域NSZone
  • 对象型变量不能作为C语言结构体(stuct/union)的成员
  • 显式转换idvoid