我有一个主应用程序,我们称它为App。
它链接了两个静态库StatLib1和StatLib2。
StatLib1链接StatLib2库。
如您所见,StatLib2库链接了两次。
在StatLib2库的类别中,我正在做一些令人毛骨悚然的事情:
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"test");
[self itk_swizzleInstanceMethodWithSelector:@selector(someMethod:)
withNewSelector:@selector(itk_someMethod:)];
});
}
test
被记录两次,这意味着方法将恢复为原始状态。我确定这是问题所在,因为当我在App目标上删除StatLib2的链接时,不会发生这种情况。
首先,为什么会这样?
如何解决此问题,而无需实际删除App目标上的StatLib2链接?
最佳答案
首先,静态库只是对象文件的存档,因此
您不能真正将一个静态库链接到另一个静态库。
可能发生的是将StatLib2的所有对象都复制到了
StatLib1。稍后,当应用程序链接时,StatLib2的另一个副本
被添加到可执行文件中。
因此,您以load
方法的两个“实例”结尾,每个实例都有自己的static dispatch_once_t onceToken
。当类被调用时,这两种方法
加载,并且每个执行其自己的dispatch_once()
块。
这也由输出显示
NSLog(@"test: class=%p, token=%p", self, &onceToken)
test: class=0x7fff7c76cdc8, token=0x100021f60
test: class=0x7fff7c76cdc8, token=0x100021f98
该类是相同的(因为它是同一类的类别),但是
onceToken
是不同的。作为解决方案,您只应将最终可执行文件链接到两者
静态库。
关于iphone - 多个静态库,困惑和dispatch_once,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20981184/