由"arc什么时候起作用?"问题发散一下

之前遇到有人问我:“arc什么时候起作用?”。我的认为是在使用alloc,init,copy,mutableCopy,new这几个家族的方法后,arc已经起作用

ARC的约定

使用ARC之后一个费解的地方是,一个方法生成的对象,没有任何附加标示,ARC怎么知道生成的对象是不是autorelease的呢?

@interface Mark : NSObject  
+ (instancetype)markWithMark:(NSString *)mark; // 1  
- (instancetype)initWithMark:(NSString *)mark; // 2  
@end 

这是非ARC时常用的手段,1、生成autorelease对象,2、生成普通对象,而现在ARC不能调用autorelease,使用时怎么能知道呢?

{  
    // ...  
    Mark *mark1 = [Mark  markWithMark:@"我是mark"];  
    Mark *mark2 = [[Mark alloc] initWithMark:@"woshimark"];  
} 

使用约定,NS定义了下面三个编译属性

#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))  
#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))  
#define NS_RETURNS_INNER_POINTER __attribute__((objc_returns_inner_pointer))  

这三个属性是Clang自己使用的标示,除非特殊情况不要自己使用,但是这些对理解ARC是很有帮助的。

关于oc有一个概念叫做 Method family:

An Objective-C method may fall into a method family, which is a conventional set of behaviors ascribed to it by the Cocoa conventions.

指的是命名上表示一类型的方法,比如- init和- initWithMark:都属于init的family

于是编译器约定,对于alloc,init,copy,mutableCopy,new这几个家族的方法,后面默认加NS_RETURNS_RETAINED标识;而其他不指名标识的family的方法默认添加NS_RETURNS_NOT_RETAINED标识

也就是说刚才的方法,在编译器看来是这样的:

@interface Mark : NSObject  
+ (instancetype)markWithMark:(NSString *)mark NS_RETURNS_NOT_RETAINED; // 1  
- (instancetype)initWithMark:(NSString *)mark NS_RETURNS_RETAINED; // 2  
@end 

这也就是为什么ARC下面,不能把一个属性定义成名字是这样的:

@property (nonatomic, copy) NSString *newMarkStr; // 编译器不允许 
  • newMarkStr就成了new家族的方法,内存就不对了

对于NS_RETURNS_INNER_POINTER这货,主要使用在返回的是一个对象的内部C指针的情况,如NSString的方法:

- (__strong const char *)UTF8String NS_RETURNS_INNER_POINTER; 
Tip----Clang

关于Clang的一份ARC的详细文档,有兴趣的可以仔细研究一下文档里面的说明和例子,很有帮助。
Clang:是一个C、C++、Objective-C和Objective-C++编程语言的编译器前端。它采用了底层虚拟机(LLVM)作为其后端。它的目标是提供一个GNU编译器套装(GCC)的替代品。作者是克里斯·拉特纳(Chris Lattner),在苹果公司的赞助支持下进行开发,而源代码授权是使用类BSD的伊利诺伊大学厄巴纳-香槟分校开源码许可。Clang主要由C++编写。
Clang性能:测试证明Clang编译Objective-C代码时速度为GCC的3倍,还能针对用户发生的编译错误准确地给出建议。
GCC与Clang区别
GCC特性:除支持C/C++/ Objective-C/Objective-C++语言外,还是支持Java/Ada/Fortran/Go等;当前的Clang的C++支持落后于GCC;支持更多平台;更流行,广泛使用,支持完备。
Clang特性:编译速度快;内存占用小;兼容GCC;设计清晰简单、容易理解,易于扩展增强;基于库的模块化设计,易于IDE集成;出错提示更友好。
Clang采用的license是BSD,而GCC是GPLv3。

你可能感兴趣的:(由"arc什么时候起作用?"问题发散一下)