———————————————————————————————————————————

ARC的概念及原理



(1)指针分类



强指针:默认情况下,所有的指针都是强指针,关键字strong



弱指针:_ _weak 关键字修饰的指针。



声明一个弱指针如下:



_ _weak Person *p;  (注意:这里的weak前面是两个下划线,且两个下划线之间没有空格!)





(2)ARC



Automatic Reference Counting,自动引用计数。



在工程中十分的简单,和往常一样编写代码就好,只不过永远不写retain、release和autorelease就好!这也是ARC基本原则。





(3)ARC工作原理及判断准则



工作原理:   ARC是OC编译器的特性,而不是运行时特性或者垃圾回收机制,ARC所做的只不过是在代码编译时为你自动在合适的位置插入release或者autorelease。



判断准则:   (只要没有强指针指向对象,对象就会被释放)

当使用ARC的时候,我们要暂时忘记“引用计数器”,因为判断标准变了。(标准不再是retainCount是否为0,而是有没有强指针指向)







★注意:



对于强指针指向的对象,一旦强指针指向了别处,那么对象内存空间就被释放。



如果对象同时被一个强指针和一个弱指针指向,强指针一旦指向别处,那么对象内存空间也会释放,而指向该对象的弱指针被赋值nil。(这句话告诉我们,强指针指向对象并持有该对象,而弱指针指向对象却不持有该对象)





代码:



#import <Foundation/Foundation.h>



@interface Car : NSObject

-(void)run;

@end



@implementation Car

-(void)run

{

    NSLog(@"Car run!");

}



- (void)dealloc

{

    NSLog(@"Car dealloc!");

}

@end



int main(int argc, const char * argv[]) {

    @autoreleasepool {

//        在iOS5以后,默认的都是ARC机制

//        ARC不能使用release、autorelease、retainCount和retain

//        ARC写允许重写dealloc方法,但是不能调用 [super dealloc];

        

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

        [car1 run];

    }//执行完这句话car1的内存空间释放

    NSLog(@"123456789");

    return 0;

}





———————————————————————————————————————————

ARC下 单对象的内存管理



代码:



#import <Foundation/Foundation.h>



@interface Car : NSObject

@property int speed;

-(void)run;

@end



@implementation Car

-(void)run

{

    NSLog(@"Car run!");

}



- (void)dealloc

{

    NSLog(@"Car dealloc!");

}

@end



int main(int argc, const char * argv[]) {

    @autoreleasepool {

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

//        

//        car=nil;

////        car在指向nil的时候是会被立即释放的,因为car被赋值nil,原来在堆区中car指向的内存空间没有了强指针的指向,所以内存释放。

////       因为car被设置为了nil,所以下面两行相当于是对nil进行的操作 nil.speed=12; ,但是对nil的操作是可行的却没变化的,所以输出的值car.speed还是0

//        car.speed=12;

//        NSLog(@"car.speed=%d",car.speed);

        

        

//        car1 和 car2 指向的是同一个内存空间

//        __strong Car *car1=[[Car alloc]init];//强指针也是可以加上 __strong 来显性修饰的

//        

//        __weak Car *car2=car1;

//        

//        car2=nil;//弱指针car2被赋值为nil,但是强指针car1仍指向原内存空间,所以说在执行完 car2=nil; 之后,原内存空间并不会被释放。

//        

//        car1=nil;//强指针car1被赋值为nil,那么原内存空间会在语句 car1=nil; 执行完后立即释放

//        

//        NSLog(@"**********");







//        注意:

//        ①:

//        __weak Car *car3=[[Car alloc]init];

//        __strong Car *car4=car3;

//        如果是这种写法,一开始在声明car3的时候就没有强指针指向,那么声明完car3之后内存立即释放(这句话也是完全没有意义的!)

        

//        ②:

//        __strong Car *car5=[[Car alloc]init];

//        __strong Car *car6=car5;

        

//        car5=nil;

//        NSLog(@"***********");

//        如果是两个强指针指向同一个内存区域,car5赋值nil之后,car6还指向原内存地址,所以内存并没有释放,而是在自动释放池大括号结束时释放        

    }

    return 0;

}





———————————————————————————————————————————

ARC下 多对象内存管理



这个地方没有什么好说的,如果在程序中一个实例对象中的实例变量是另一个类型的实例对象,那么我们应该将他设置成强指针类型,因为我们要用到他,用它的时候不能让他成为nil。



设置变量的时候我们可以:



@property (nonatomic,strong) Dog *dog;  //当然这里是默认的



还有就是用@property增强来设置实例变量的时候

(下面等同)

strong —————retain

weak—————assign





———————————————————————————————————————————

ARC下 循环引用问题



代码:



Dog.h



#import <Foundation/Foundation.h>

@class Person;



@interface Dog : NSObject

@property(nonatomic,strong)Person *owner;

@end





Dog.m



#import "Dog.h"



@implementation Dog

- (void)dealloc

{

    NSLog(@"Dog dealloc!");

}

@end





Person.h



#import <Foundation/Foundation.h>

@class Dog;



@interface Person : NSObject

@property(nonatomic,weak)Dog *dog;

@end





Person.m



#import "Person.h"



@implementation Person

- (void)dealloc

{

    NSLog(@"Person dealloc!");

}

@end





main.m



#import <Foundation/Foundation.h>

#import "Person.h"

#import "Dog.h"



int main(int argc, const char * argv[]) {

    @autoreleasepool {

        Person *p=[[Person alloc]init];

        

        Dog *dog=[[Dog alloc]init];

        

//        不加下面两句话的时候(没有互相建立关系的时候),他们是可以释放的。但是他们之间一旦有了关系,就无法被释放(两个都是strong类型)

        p.dog=dog;

        

        dog.owner=p;

//        想要解决这个问题,其实和前面在MRC机制下差不多,我们只需要将他们两个其中一个的类型设置为weak,这样就可以解决循环调用的问题了。

//        比如我们将Person 中的Dog类型的参数设置为weak,那么他就会先释放,然后dog的owner参数也会释放,这样两个都能释放了

    }

    return 0;

}





附加:ARC下 的 @property 参数



ARC中的 @property



strong:用于OC对象,相当于MRC中的retain

weak:用于OC对象,相当于MRC中的assign(在定义@property类型的时候就不要加两个下划线了)

assign:用于基本数据类型,跟MRC中的assign一样

copy:用于NSString,跟MRC中的copy一样



★在ARC下解决循环引用问题,一边用strong,一边用weak





———————————————————————————————————————————

ARC的兼容和转换

①如何在ARC文件中兼容非ARC的文件

步骤就在上图了,Dog类是ARC,Car类是非ARC。那么我们就找到Car类的Compiler Flags,然后双击在里面键入 -fno-objc-arc  如下图(如果是-f-objc-arc就是兼容ARC)









②如何将MRC文件转换成ARC文件

首先确保你要转换的文件之前是一个MRC文件,也就是将ARC的开关关闭

然后按照下图的操作,先选定该target,然后Edit,然后Convert,然后To Objective-C ARC…

最后按照提示下一步,你就会发现,你的代码发生了一些改变:

这就是将MRC文件转换成ARC文件的方法。但是,注意,这种方法不一定100%成功,可能会转换错误,所以用的时候要谨慎!





———————————————————————————————————————————

版权声明:本文为博主原创文章,未经博主允许不得转载。

Objective-C 【This is ARC】的更多相关文章

  1. Django集成Markdown编辑器【附源码】

    专注内容写作的你一定不要错过markdown 简单介绍 markdown是一种标记语言,通过简单的标记语法可以使普通的文本内容具有一定的格式,使用非常简单,学习成本极低 目前各大Blog平台都已支持m ...

  2. 【无旋 treap】例题

    [bzoj3223]文艺平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[ ...

  3. 【硬件基础知识】指令集框架(ISA:Instruction Set Architecture)

    指令框架(ISA:Instruction Set Architecture) 定义 指令集架构(英语:Instruction Set Architecture,缩写为ISA),又称指令集或指令集体系, ...

  4. 【开源】简单4步搞定QQ登录,无需什么代码功底【无语言界限】

    说17号发超简单的教程就17号,qq核审通过后就封装了这个,现在放出来~~ 这个是我封装的一个开源项目:https://github.com/dunitian/LoTQQLogin ————————— ...

  5. 【夯实PHP基础】PHP数组,字符串,对象等基础面面观

    本文地址 分享提纲 1.数组篇 2.字符创篇 3.函数篇 4.面向对象篇 5.其他篇 /*************************** 一.数组篇 Begin***************** ...

  6. 【Java学习系列】第3课--Java 高级教程

    本文地址 可以拜读: 从零开始学 Java 分享提纲: 1. Java数据结构 2. Java 集合框架 3. Java泛型 4. Java序列化 5. Java网络编程 6. Java发送Email ...

  7. 【夯实PHP基础】nginx php-fpm 输出php错误日志

    本文地址 原文地址 分享提纲: 1.概述 2.解决办法(解决nginx下php-fpm不记录php错误日志) 1. 概述 nginx是一个web服务器,因此nginx的access日志只有对访问页面的 ...

  8. 分布式学习系列【dubbo入门实践】

    分布式学习系列[dubbo入门实践] dubbo架构 组成部分:provider,consumer,registry,monitor: provider,consumer注册,订阅类似于消息队列的注册 ...

  9. 【第三篇】ASP.NET MVC快速入门之安全策略(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

随机推荐

  1. Codeforces Round #335 (Div. 2) C. Sorting Railway Cars 动态规划

    C. Sorting Railway Cars Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.codeforces.com/conte ...

  2. 关于C#资源文件操作的总结

    // 在这里,我来总结一下关于资源文件的相关操作. //1. 比较常见的有获取资源文件对应的文件流,然后转换到相对应的文件 // 比较典型的做法是通过代码程序集加载指定资源 // 如下通过Assemb ...

  3. OpenGL 4.0 GLSL 实现 投影纹理映射(Projective Texture Mapping) (转)

    http://blog.csdn.net/zhuyingqingfen/article/details/19331721   分类: GLSL  投影纹理映射 (projective texture ...

  4. 使用 Team Foundation 版本控制命令

    使用 Team Foundation 版本控制命令 Visual Studio 2013   其他版本 Visual Studio 2010 Visual Studio 2008 Visual Stu ...

  5. ext2文件系统

    2.1. 总体存储布局 我们知道,一个磁盘可以划分成多个分区,每个分区必须先用格式化工具(例如某种mkfs命令)格式化成某种格式的文件系统,然后才能存储文件,格式化的过程会在磁盘上写一些管理存储布局的 ...

  6. 在MVC中动态读取JSON数据创建表格

    //使用getJSON // ("@Url.Action("GetAllUsers","User")" ,json文件的路径.也可以是 /M ...

  7. linux服务器之redis

    linux环境下安装redis服务器: redis下载地址:http://redis.io/download $ wget http://download.redis.io/releases/redi ...

  8. GNU C/C++ __attributes__ GCC中的弱符号与强符号

    最近在看一些源代码,遇到了一些使用__attribute__修饰函数和变量的属性方面的代码,不是太了解,很是汗颜,再此做个总结:   GCC使用__attribute__关键字来描述函数,变量和数据类 ...

  9. rm反向删除的几种方法

    关键词:rm  删除 反向 参考: http://blog.sina.com.cn/s/blog_67e34ceb01014930.html http://bbs.csdn.net/topics/39 ...

  10. 从零开始学JAVA(06)-WebService_Jersey_Restful

    由于项目上需要写一个简单的评价系统,像银行MM前面的那种非常满意.满意.不满意那种,结合一个安卓的APP一起使用.由于使用3G网页通讯,个人认为http这种方式更合适.曾经听在Delphi鸟窝群的白雪 ...