我有一个主应用程序,我们称它为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/

10-13 05:03