非ARC项目中使用的__strong限定符

时间:2013-09-04 09:20:19

标签: ios objective-c automatic-ref-counting

该项目未启用ARC,但我们(错误地)使用符合ARC的代码库 - 特别是创建单个对象,如GCDSingleton.h中定义的那样:

#define DEFINE_SHARED_INSTANCE
+ (id)sharedInstance
{
  static dispatch_once_t pred = 0;
  __strong static id _sharedObject = nil;
  dispatch_once(&pred, ^{
    _sharedObject = ^{return [[self alloc] init];}();
  });
  return _sharedObject;
}

即使使用__strong限定符定义共享对象,这似乎也能正常工作。我想知道为什么这不会导致错误或至少是警告(最新的Xcode 4.6和ios 6 sdk)。此外,由于项目未启用ARC,__strong限定符究竟在做什么,如果有的话?

1 个答案:

答案 0 :(得分:4)

在MRC代码中,__strong被忽略。

我试图编译一个简单的例子

#import <Foundation/Foundation.h>

int main(int argc, char const *argv[]) {
    __strong NSString * foo = [[NSString alloc] initWithFormat:@"Hello, %s", argv[1]];
    NSLog(@"%@", foo);
}

使用ARC

clang -fobjc-arc test.m -S -emit-llvm -o arc.ir

没有ARC

clang -fno-objc-arc test.m -S -emit-llvm -o mrc.ir

并扩散llvm IR输出。

以下是diff mrc.ir arc.ir

的结果
54a55,56
>   %17 = bitcast %0** %foo to i8**
>   call void @objc_storeStrong(i8** %17, i8* null) nounwind
63a66,67
> declare void @objc_storeStrong(i8**, i8*)
> 

所以基本上ARC和MRC之间的唯一区别是添加了objc_storeStrong电话。


顺便说一下,没有__strong限定符的相同代码会生成相同的结果,因为__strong是ARC中变量的默认限定符。