• ARC在工程上的相关设置


    Automatic Reference Counting (ARC) 是一个编译期的技术,利用此技术可以

    简化Objective-C编程在内存管理方面的工作量。

    ARC在Xcode4.2中引入,在Mac OS X v10.6,v10.7 (64位应用),iOS 4,iOS 5中支持,Xcode4.1中不支持这个技术。

    虽然ARC是与iOS5一同推出,但是由于ARC的实现机制是在编译期完成,所以使用ARC之后App仍然可以支持iOS4.3。

    稍微需要注意的是,如果要在ARC开启的情况下支持iOS4.3,需要将weak关键字换成 __unsafe_unretained,

    另外还有一些细节需要处理。

    如下图就是Xcode集成的将非ARC工程转换成ARC工程的工具。

    首先,ARC是LLVM3.0编译器的特性,而老的工程特别是Xcode3时代的工程的默认编译器很可能是GCC或者LLVM-GCC,因此第一步就是确认编译器是否正确。在Project设置面板,选择target,在Build Settings中将Compiler for C/C++/Objective-C选为Apple LLVM compiler 3.0或以上。为了确保之后转换的顺利,在这里我个人建议最好把Treat Warnings as Errors和 Run Static Analyzer都打开,确保在改变编译器后代码依旧没有警告或者内存问题。

    在创建工程的时候,我们可以指定工程是否使用ARC技术,如下图

    选中表示支持ARC,

    如果是你拿到的工程,那么可以通过设置来改变,如下图所示

    如果不容易找到,可以在设置的右上角搜索框输入Automatic做一个过滤。

    另外,为了兼容第三方的非ARC开源库,你也可以在工程中随意使用编译参数:-fno-objc-arc ,

    这个参数允许对部分文件关闭ARC。

    直接在targets->build phases中修改compiler Flags,是否支持arc。

    添加:-fobjc-arc,就可以让旧项目支持arc。如果想让原来支持arc的不使用arc则添加-fno-objc-arc

    如果只想对某个.m文件不适应ARC,可以只针对该类文件加上

    -fno-objc-arc 编译,如下图。

    同样你可以添加编译标记-fobjc-arc来让你的工程支持ARC。

    ARC的工程,转换规则包括:

            1.去掉所有的retain,release,autorelease

            2.把NSAutoRelease替换成@autoreleasepool{}块

            3.把assign的属性变为weak

    使用ARC的一些强制规定

            1.不能直接调用dealloc方法,不能调用retain,release,autorelease,reraubCount方法,

            包括@selector(retain)的方式也不行


            2.截图租户事故宣布dealloc方法来管理一些资源,但不能用来释放实例变量,

           也不能在dealloc方法里面去掉[super dealloc]方法,在ARC下父类的dealloc同样由编译器来自动完成

            3.Core Foundation类型的对象任然可以用CFRetain,CFRelease这些方法

            4.不能在使用NSAllocateObject和NSDeallocateObject对象

            5.不能在c结构体中使用对象指针,如果有类似功能可以创建一个Objective-c类来管理这些对象

            6.在id和void *之间没有简便的转换方法,同样在Objective-c和core Foundation

            类型之间的转换都需要使用编译器制定的转换函数

            7.不能再使用NSAutoreleasePool对象,ARC提供了@autoreleasepool块来代替它,这样更加有效率

            8.不能使用内存存储区(不能再使用NSZone)

            9.不能以new为开头给一个属性命名

            10.声明outlet时一般应当使用weak,除了对StoryBoard 这样nib中间的顶层对象要用strong

            11.weak 相当于老版本的assign,strong相当于retain

    • strong. 这是以前的 “retain” 的一个代号。 strong 属性将会成为它所指对象的所有者。
    • weak. 这个属性表示弱引用指针。 当它指向的对象被销毁时,它会被自动的设置成 nil。 记住,在 outlet 上使用它
    • unsafe_unretained. 这和以前的 “assign” 等同。 你只需要在一些例外的情况下会应道它,并且当你在给 iOS 应用时,后面会讲到更多。
    • copy. 这个和之前是一样的。 它创建一个对象的拷贝,并且创建一个强引用关系。
    • assign. 你不再允许在对象上用这个修饰符, 但你仍然能在简单类型的值,比如 BOOL,int 和 float 中用到它。

     使用关键字”strong”进行标志,它意味着只要该指针指向某个对象,那么这个对象就不会被销毁。

    反过来说,ARC的一个基本规则即使,只要某个对象被任一strong指针指向,那么它将不会被销毁。

    如果对象没有被任何strong指针指向,那么就将被销毁。在默认情况下,所有的实例变量和局部变量

    都是strong类型的。可以说strong类型的指针在行为上和MRC时代retain的property是比较相似的。

     

    既然有”strong”,那肯定有”weak”。

    weak类型的指针也可以指向对象,但是并不会持有该对象。

    根据之前提到的“只要某个对象被任一strong指针指向,那么它将不会被销毁。如果对象没有被任何strong指针

    指向,那么就将被销毁”原则,此时指向对象的指针中没有strong类型的指针,对象将被销毁。同时,在ARC机制

    作用下,所有指向这个对象的weak指针将被置为nil。这个特性相当有用,相信无数的开发者都曾经被指针指向

    已释放对象所造成的EXC_BAD_ACCESS困扰过,使用ARC以后,不论是strong还是weak类型的指针,

    都不再会指向一个dealloced的对象,从根源上解决了意外释放导致的crash。

    不过在大部分情况下,weak类型的指针可能并不会很常用。比较常见的用法是在两个对象间存在包含关系时:

    对象1有一个strong指针指向对象2,并持有它,而对象2中只有一个weak指针指回对象1,从而避免了循环持有。

    一个常见的例子就是oc中常见的delegate设计模式,viewController中有一个strong指针指向它所负责

    管理的UITableView,而UITableView中的dataSource和delegate指针都是指向viewController的weak指针。

    可以说,weak指针的行为和MRC时代的assign有一些相似点,但是考虑到weak指针更聪明些(会自动指向nil),

    因此还是有所不同的。 

    如图参考

    注意类似下面的代码似乎是没有什么意义的: 

    __weak NSString *str = [[NSString alloc] initWithFormat:…]; 
    NSLog(@"%@",str); //输出是"(null)"

    由于str是weak,它不会持有alloc出来的NSString对象,因此这个对象由于没有有效的strong指针指向,

    所以在生成的同时就被销毁了。如果我们在Xcode中写了上面的代码,我们应该会得到一个警告,因为

    无论何时这种情况似乎都是不太可能出现的。你可以把weak换成strong来消除警告,或者直接前面

    什么都不写,因为ARC中默认的指针类型就是strong。

    property也可以用strong或weak来标记,简单地把原来写retain和assign的地方替换成strong或者

    weak就可以了。

    @property (nonatomic, strong) NSString *firstName; 
    @property (nonatomic, weak) id  delegate;

    详细参考苹果的官方文档,在xcode4.2以上版本中,在控制面板Organizer中搜索ARC

    参考

    http://www.onevcat.com/2012/06/arc-hand-by-hand/

    http://www.lanrenios.com/tutorials/all/2012/1024/221.html

  • 相关阅读:
    让div 充满整个body GIS
    fortuneclient 学习 (客户端接受数据) GIS
    错误 1 error C1083: 无法打开包括文件:“QNetworkProxy”: No such file or directory GIS
    qt fortuneserver 例子学习 ( 给客户端发送消息) GIS
    new操作符(new operator) 和 new操作(operator new)的区别。 GIS
    qt 控件 GIS
    c++ 顺序容器 GIS
    将一个div 分成两列 也可以分成多列 GIS
    控件模板 1
    WPF简单写写。。。
  • 原文地址:https://www.cnblogs.com/jiangshiyong/p/3007080.html
Copyright © 2020-2023  润新知