3

该项目未启用 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 限定符到底在做什么(如果有的话)?

4

1 回答 1

5

在 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);
}

带弧

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 中变量的默认限定符。

于 2013-09-05T17:53:55.663 回答