您的位置:首页 > 移动开发 > Objective-C

黑马程序员-10-Objective-C学习笔记(ARC)

2014-10-05 00:00 225 查看
摘要: ARC是什么,ARC有什么用,ARC如何使用,工程ARC和非ARC之间转换

---------------------- Java培训.Net培训Android培训IOS培训、期待与您交流! ----------------------

1. ARC是什么

(1) 由于在IOS开发中如果没有ARC程序员要花大量的精力去管理内存,那么开发效率就大大地降低了。

(2) ARC( Auto Reference Counting )是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain、release、autorelease语句。你不再需要担心内存管理,因为编译器为你处理了一切

(3) ARC 是编译器特性,而不是 iOS 运行时特性,它也不是类似于其它语言中的垃圾收集器。因此 ARC 和手动内存管理性能是一样的,有时还能更加快速,因为编译器还可以执行某些优化

2. ARC有什么用

其实ARC既然是编译器特性,那么它的作用是帮助我们自动生成内存管理代码,既然会自动生成内存管理代码,肯定不会随便生成,它肯定是依据一定的原则来判断是否生成:

a. ARC管理内存的原则

ARC管理内存的原则 : 只要还有一个强指针变量指向对象,对象就会保持在内存中,如果没有强指针指向该对象,该对象就会被release

b. 强指针 和 弱指针

(1) 强指针 : 把一个指针说明为强指针的关键字是 __strong ,默认情况下所有对象实例的变量和局部变量都是强指针

(2) 弱指针 : 把一个指针说明为弱指针的关键字是 __weak

/************************************* Student.h ***********************************************/
#import<Foundation/Foundation.h>

@interface Student : NSObject

@property (noatomic,assign) int age;

@end;

/************************************* Student.m ***********************************************/
#import "Student.h"
@implementation Student

-(void)dealloc
{
NSLog(@"Student is dealloc");
// [super dealloc];                                                        // 在ARC中会自动插入这句代码
}
@end

/************************************* 强指针 ***********************************************/

#import "Student.h"

int main()
{
Student *s = [[Student alloc] init];                                        // 默认情况下都是强指针,因此这句相当于 : __strong Student *s = [[Student alloc] init];

/* 强指针转移指向的 ARC处理:
// 强指针转移指向的时候会插入以下代码 :
[s release];
s = nil;
s = [[Student alloc] init];                                                 // 这时候 s 转移指向到另外一个新的对象,那么原来旧的对象就没有强指针指向,那么ARC会在此代码之前加入左边的代码
*/

/* 强指针被置为空时的 ARC处理:
// 强指针被置为空时会插入以下代码 :
[s release];
s = nil;                                                                    // 当强指针被置为空的时候,相当于Student对象在内存中失去强指针的指向,那么ARC会加入左边的代码
*/

/* ARC 会在代码块结束前对对象进行一些销毁工作
[s release];
s = nil;
*/
return 0;
}                                                                              // 程序执行到这里的时候局部变量 s 被回收了,没有强指针指向该对象,左边return前的代码,因此会打印 : Student is dealloc

/************************************* 弱指针 ***********************************************/

#import "Student.h"
int main()
{
Student *s = [[Student alloc] init];                                        // 默认情况下都是强指针,因此这句相当于 : __strong Student *s = [[Student alloc] init];

/* 弱指针指向一个新创建的对象,这种做法毫无意义,因为在这行执行后该对象会立即销毁
__weak Student *s1 = [[Student alloc] init];                               // 对于这种写法,根据ARC判断原则,在这行代码执行后会插入内存管理代码把该对象销毁,因此会打印 : Student is dealloc
*/
__weak Student *s1 = s;                                                     // 定义一个弱指针来保存强指针的内存地址

s = nil;                                                                    // 强指针被置为空,那么对象在内存中只有弱指针指向该对象,根据ARC管理内存的原则,会插入内存管理代码把该对象销毁,                                                                                            // 因此会打印 : Student is dealloc
return 0;
}


3. ARC使用注意

(1) 不能调用release、retain、autorelease、retainCount

(2) 可以重写dealloc,但是不能调用[super dealloc]

(3) @property : 想长期拥有某个对象,应该用strong,其他对象用weak

(4) 其他基本数据类型依然用assign

(5) 两端互相引用时,一端用strong、一端用weak

/************************************* Dog.h ***********************************************/
#import<Foundation/Foundation.h>
@class Student

@interface Dog : NSObject

/* 没有ARC之前的写法
@property (noatomic,retain) NSString *name;
*/
@property (noatomic,strong) NSString *name;                                    // 使用ARC后对于OC对象把retain策略改为strong策略,它生成的set方法跟retain策略的set方法一样,但在dealloc方法中会自动
// 插入 [name release];来销毁对象

@property (noatomic,weak) Student *owner;                                      // 循环引用其中一方使用 strong ,另外一方使用 weak

@end

/************************************* Dog.m ***********************************************/
#import "Dog.h"
#import "Student.h"

@implementation Dog
-(void)dealloc
{
NSLog(@"Dog is dealloc");
// [super dealloc];                                                         // 重写dealloc,但是不能调用[super dealloc],ARC会自动帮助我们插入
}
@end

/************************************* Student.h ***********************************************/
#import<Foundation/Foundation.h>
@class Dog

@interface Student : NSObject

@property (noatomic,assign) int age;                                          // 对于基本数据类型依然使用 assign 策略

@property (noatomic,strong) Dog *dog;                                         // 循环引用其中一方使用 strong ,另外一方使用 weak

@end;

/************************************* Student.m ***********************************************/
#import "Student.h"
#import "Dog.h"

@implementation Student

-(void)dealloc
{
NSLog(@"Student is dealloc");
}
@end

/************************************* main.m ***********************************************/
#import "Student.h"
#import "Dog.h"

int main()
{
Student *s = [[Student alloc] init];
Dog *dog = [[Dog alloc] init];

dog.name = @"mike";
dog.owner = s;

s.age = 22;
s.dog = dog;

return 0;
}                                                                                  // 程序结束对象被回收,强指针本置为空,打印结果 : Student is dealloc Dog is dealloc



4. Xcode对ARC 开启和禁止

要想将非ARC的代码转换为ARC的代码,大概有2种方式:
(1) 使用Xcode的自动转换工具
(2) 手动设置某些文件支持ARC

a. Xcode把非ARC代码转化为ARC模式

Xcode带了一个自动转换工具,可以将旧的源代码转成ARC模式
(1) ARC是LLVM 3.0编译器的特性,而现有工程可能使用老的GCC 4.2或LLVM-GCC编译器,因此首先需要设置使用LLVM 3.0编译器:(现使用的XCode4.5,LLVM 3.0已经升级到LLVM 4.1)

(2) 最好也选上Warnings中的Other Warning Flags 为 -Wall,这样编译器就会检查所有可能的警告,有助于我们避免潜在的问题



(3) Build Options下面的Run Static Analyzer选项也最好启用,这样每次Xcode编译项目时,都会运行静态代码分析工具来检查我们的代码



(4) 设置"Objective-C Automatic Reference Counting"选项为YES,不过Xcode自动转换工具会自动设置这个选项,这里只是说明一下如何手动设置



(5) 打开Xcode的自动转换工具,选择要转换的文件



(6) 点击Check按钮,Xcode可能会弹出对话框提示项目不能转换为ARC,需要你准备好转换(这里暂时省略详细说明)



(7) 如果没有什么警告、错误了,就会弹出一下提示窗口



(8) 点击Next,几秒钟后,Xcode会提示所有文件的转换预览,显示源文件的所有改变。左边是修改后的文件,右边是原始文件。在这里你可以一个文件一个文件地查看Xcode的修改,以确保Xcode没有改错你的源文件:



(9) 点击Save即可完成转换

注意 : 自动转换之后,Xcode会移除所有retain、release、autorelease调用,这可能会导致代码出现其它警告、无效语法等,这些都需要自己手工进行修改

b. 手动 开启 和 禁止 某些文件的ARC

(1) 在Compiler Flags一列加上-fobjc-arc就表示开启这个.m文件的ARC
(2) 在Compiler Flags一列加上-fno-objc-arc就表示禁止这个.m文件的ARC





---------------------- Java培训.Net培训Android培训IOS培训、期待与您交流! ----------------------
详情请查看:http://edu.csdn.net/heima
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: