ARC管理内存

ARC:autommatic reference counting
当程序执行某方法时,会从内存中名为栈(stack)区域分配一块内存空间,这块内存空间称为帧(frame)。帧负责保存程序在方法内声明的变量的值。在方法内声明的变量称为局部变量(local variable)。
堆(heap)是指内存中的另一块区域,与栈分开。为这两类内存区域分别名堆和栈,形象描述。栈:先进后出的规则保存一组帧。堆:包含大量无序的活动对象,需要通过指针保存这些对象在堆中的地址。
当应用向某个类发送alloc消息时,系统会从堆中分配出一块大小足够容纳对象所有实例变量的内存。
指向不存在的对象的指针称为空指针(dangling pointer)或者空引用(dangling reference)。
当两个或两个以上的对象相互之间有强引用特性的指针关联时,就会产生强引用循环(strong reference cycle)
使用__weak关键字,可以将某个变量声明为具有弱引用特性。
请注意实例变量和存取方法的声明不会出现在文件中,编译器会在编译时自动加入这些代码。
【ARC管理内存】具有弱引用特征的指针指向的对象释放后,指针会自动设置为nil。
强引用,不会自动设置为nil,会变成空指针,访问会引起crash。
@property(attribute):任何属性都有三个特征(attribute),每个特征有多种不同的可选类型,其中每个特征,都有默认的。默认类型可以忽略写上去。
1.多线程特性(Multi-threading attribute):nonatomic、atomic。nonatomic不是默认类型,所以声明属性时,需要明确写上。
2.内存管理特征(Memory management attribute):strong、weak、copy、unsafe_unretained:这些类型决定相应的实例变量将如何引用对象。对于不指向对象的属性(基本类型),不需要做内存管理,应选用unsafe_unretained(存取方法会直接变为实例变量赋值,曾用assign名称代替过。)。unsafe只是针对弱引用而言,它会令弱引用指针在指向对象释放时,不会自动设置nil,而是成空指针。unsafe_unretained是非对象属性的默认值。
strong:对于指向Objective-C对象的属性,四种类型都有可能,默认为strong类型,但是建议明确写出,apple会暗改。
copy:通常情况下,当某属性是指向其他对象的指针,且该对象的类有可修改的子类时,该属性的内存管理特征设置为copy。这是为了防止当用可改的子类对象指针赋值给自身不可改对象指针时,可改对象指针改变,导致不可变对象指针变成可变。从而copy为了防止这个行为,这种编写具有“防御性”的代码。但是如果可变对象设置成copy,而赋值不可变对象会浪费内存控制。
3.读/写特征(Read/Write attribute):readwrite、readonly。默认是readwrite。如果覆盖存和取方法(或者只读属性覆盖取方法),那么编译器就不会再自动创建向相应的实例变量。
属性会自动生成存取方法,也会自动声明和创建实例变量。
在头文件生命属性时,只会生成存取方法的声明。为了让属性生成实例变量并实现存取方法,该属性必须被合称(synthesized)。通常情况下,编译器会自动合成属性并生成默认的实例变量和存取方法。但是需要自定义属性的合成方式,可以在实现文件中使用@synthesize指令。

@implementation ClassName //创建存取方法,方法名为x和setX; //同时创建实例变量_x @synthesize x = _x; @end

以上代码和编译器自动合成代码的效果相同。赋值号左边的x表示需要创建存取方法,方法名是x和setX。右边的_x表示需要创建实例变量名,变量名为_age。也可以不写变量名,这样实例变量的变量名会和方法名相同。
以前静态分析器用来为代码自动插入所有的retain和release调用,这才导致ARC诞生。
手动引用计数(manual reference counting):在以前不支持ARC前,只能用这个来管理内存。还需要理解自动释放池(autorelease pool)。
ARC管理内存
文章图片
当某对象收到autorelease消息时,某个自动释放池会成为该对象的临时拥有者 ARC管理内存
文章图片
@autoreleasepool

    推荐阅读