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

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. .NET程序性能的基本要领

    前几天在老赵的博客上看到,Bill Chiles (Roslyn 编译器的Program Manager)写了一篇文章叫做<Essential Performance Facts and .NE ...

  2. C# Redis分布式缓存

    C# Redis实战(七) 七.修改数据 在上一篇 C# Redis实战(六)中介绍了如何查询Redis中数据,本篇将介绍如何修改Redis中相关数据.大家都知道Redis是key-value型存储系 ...

  3. 从ext2文件系统上读出超级块

    概述            本篇博客中,我们将仔细分析如何从格式化为ext2文件系统的磁盘中读取超级块并填充内存超级块结构,每次将一个格式化了ext2文件系统的磁盘(分区)挂载到挂载点的时候会调用该方 ...

  4. 1.4.2 solr字段类型--(1.4.2.4)使用Dates(日期)

    1.4.2 solr字段类型 (1.4.2.1) 字段类型定义和字段类型属性. (1.4.2.2) solr附带的字段类型 (1.4.2.3) 使用货币和汇率 (1.4.2.4) 使用Dates(日期 ...

  5. HttpSolrServer-采用静态工厂方法,创建HttpSolrServer单实例

    HttpSolrServer线程安全,如果使用下面构造器,必须对所有的请求重用相同的实例.如果实例在运行中创建的,它可能会导致连接泄漏.推荐的做法就是保持每个solr服务url的HttpSolrSer ...

  6. IOS NS 字符串 数组 字典 文件 动态 静态 操作

    ios 常用字符串的操作   //将NSData转化为NSString        NSString* str = [[NSString alloc] initWithData:response e ...

  7. Autel MaxiDAS DS708 Fatal Application Error illegal operation

    I get one Original Autel MaxiDAS® DS708 Update Service, after complete update, I got a message " ...

  8. spring mvc 重新定向到一个新的Url

    在写项目的时候要求根据请求的参数的不同重新将请求分发,在查阅了spring mvc的一些资料无果后(想使用拦截器去做)就没办法使用重定向的方式去写了 /** * 通过访问API的方式分发请求 * * ...

  9. Composer 中国镜像

    1.修改Composer的全局配置文件 config.json 使用sudo composer config -l -g 查看composer全局配置信息,在这些信息中查找 [home] 配置项就是 ...

  10. [转]在WPF中使用WinForm控件方法

    本文转自:http://blog.csdn.net/lianchangshuai/article/details/6415241 下面以在Wpf中添加ZedGraph(用于创建任意数据的二维线型.条型 ...