zoukankan      html  css  js  c++  java
  • Objective-C 【This is ARC】

    ———————————————————————————————————————————
    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%成功,可能会转换错误,所以用的时候要谨慎!


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

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

  • 相关阅读:
    Elasticsearch Query DSL 整理总结(三)—— Match Phrase Query 和 Match Phrase Prefix Query
    Elasticsearch Query DSL 整理总结(二)—— 要搞懂 Match Query,看这篇就够了
    Elasticsearch Query DSL 整理总结(一)—— Query DSL 概要,MatchAllQuery,全文查询简述
    Elasticsearch Java Rest Client API 整理总结 (三)——Building Queries
    Elasticsearch date 类型详解
    python 历险记(五)— python 中的模块
    python 历险记(四)— python 中常用的 json 操作
    python 历险记(三)— python 的常用文件操作
    Elasticsearch Java Rest Client API 整理总结 (二) —— SearchAPI
    Elasticsearch Java Rest Client API 整理总结 (一)——Document API
  • 原文地址:https://www.cnblogs.com/wzy294250051/p/4787879.html
Copyright © 2011-2022 走看看