什么是自动引用计数 自动引用计数(ARC,Automatic Reference Counting)是指内存管理中对引用采取自动计数的技术。要使用 ARC,需要满足以下条件:
使用 Xcode4.2 或以上版本 使用 LLVM 编译器 3.0 或以上版本 编译器选项中设置 ARC 有效 生活例子:办公室开关灯
最早进入办公室的人开灯。 count = 1 之后进入办公室的人,需要照明。 count = 2 下班离开办公室的人,不需要照明。 count = 1 最后离开办公室的人关灯。(此时已无人需要照明) count = 0 内存管理 思考方式:
自己生成的对象,自己持有 非自己生成的对象,自己也能持有 不再需要自己持有的对象时释放 非自己持有的对象无法释放 表 1- 2 对象操作与 Objective-C 方法的对应
对象操作 Objective-C方法 生成并持有对象 alloc/new/copy/mutableCopy方法 持有对象 retain方法 释放对象 release方法 废弃对象 dealloc方法 区域(zone)
NSDefaultMallocZone、NSZoneMalloc 等名称中包含的NSZone是什么呢?它是为防止内存碎片化而引入的结构。对内存分配的区域本身进行多重化管理,根据使用对象的目的、对象的大小分配内存,从而提高了内存管理的效率。但是,如同苹果官方文档 Programming With ARC Release Notes 中所说,现在的运行时系统只是简单地忽略了区域的概念。运行时系统中的内存管理本身已极具效率,使用区域来管理内存反而会引起内存使用效率低下以及源代码复杂化问题。
修饰符
__strong 修饰符 __weak 修饰符 __unsafe_unretained 修饰符 __autoreleasing 修饰符 __unsafe_unretained 修饰符正如其名 unsafe 所示,是不安全的所有权修饰符。尽管 ARC 式的内存管理是编译器的工作,但附有 __unsafe_unretained 修饰符的变量不属于编译器的内存管理对象。同附有 __weak 修饰符的变量一样,因为自己生成并持有的对象不能继续为自己所有,所以生成的对象会立即被释放。
blocks 是 C 语言的扩充功能。blocks 是带有自动变量(局部变量)的匿名函数。
截获自动变量 int main() { int dmy = 256; int val = 10; const char *fmt = "val = %d\n"; void (^blk)(void) = ^{ printf(fmt,val); }; val = 2; fmt = "These value were changed. val = %d\n"; blk(); return 0; } 结果:val = 10
分析:block 语法的表达式使用的是它之前声明的自动变量 fmt 和 val。block 表达式截获所使用的自动变量的值为瞬间值。因为 block 表达式保存了自动变量的值(截获),所以在执行 block 语法后,即使改写了 block 中使用的自动变量的值也不会影响 block 执行的结果。
需要在 block 中修改一个变量的值,需要使用 __block 说明符。
block 的实质 block 实际上是作为极普通的 C 语言源代码来处理的。通过支持 block 的编译器,含有 block 语法的源代码转换为一般 C 语言编译器能够处理的源代码,并作为极为普通的 C 语言代码被编译。
在项目导航面板中选中 main.m ,可以看到
int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } 这是 iOS 应用的入口函数。UIApplicationMain 函数会创建一个 UIApplication 对象。每个 iOS 应用都有且只有一个 UIApplication 对象(单例),该对象的作用时维护运行循环。一旦程序创建了某个 UIApplication 对象,该对象的运行循环就会一直循环下去,main() 的执行也会因此阻塞。
此外,UIApplicationMain 函数还会创建某个指定类(此处为 AppDelegate)的对象,并将其设置为 UIApplication 对象的 delegate。UIApplicationMain 函数的第三个实参为 NSString 类型,指定了该对象所属的类。UIApplication 的 delegate 都需要遵守 UIApplicationDelegate 协议。
@interface AppDelegate : UIResponder <UIApplicationDelegate>
在应用启动运行循环时,UIApplication 对象会在应用出现相应状态变化时,向其 delegate 发送特定的消息。如:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; - (void)applicationWillResignActive:(UIApplication *)application; - (void)applicationDidEnterBackground:(UIApplication *)application; - (void)applicationWillEnterForeground:(UIApplication *)application; - (void)applicationDidBecomeActive:(UIApplication *)application; - (void)applicationWillTerminate:(UIApplication *)application; UIApplication 负责建立应用程序的事件循环(Event Loop),事件循环中可以不断接收交互操作,比如屏幕触摸手势、各类传感器(重力加速器、陀螺仪等)等。