iphone - 多个静态库、swizzling 和dispatch_once

标签 iphone objective-c macos cocoa-touch cocoa

我有一个主应用程序,我们称之为应用程序
它链接两个静态库:StatLib1StatLib2
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 链接时,这种情况不会发生。

<小时/>
  1. 首先,为什么会发生这种情况?
  2. 如何解决此问题,而不实际删除 App 目标上 StatLib2 的链接?

最佳答案

首先,静态库只是目标文件的存档,所以 您无法真正将一个静态库链接到另一个静态库。 可能发生的情况是 StatLib2 的所有对象都复制StatLib1。稍后,当链接应用程序时,StatLib2 的另一个副本 添加到可执行文件中。

因此,您以 load 方法的两个“实例”结束,每个实例都有自己的 静态dispatch_once_t OnceToken。这两个方法都会在类中调用 加载后,每个都执行自己的 dispatch_once() block 。 输出也表明了这一点

NSLog(@"test: class=%p, token=%p", self, &onceToken)

test: class=0x7fff7c76cdc8, token=0x100021f60
test: class=0x7fff7c76cdc8, token=0x100021f98

类是相同的(因为它是同一个类的类别),但是 onceToken 是不同的。

作为解决方案,您应该只将最终的可执行文件链接到两者 静态库。

关于iphone - 多个静态库、swizzling 和dispatch_once,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20981184/

相关文章:

objective-c - 如何在Cocoa中的App包中包含框架安装包?

macos - OSX 10.13.2 上的 pyethapp 安装问题

ios - 在多个对象上渲染多个纹理的问题

objective-c - cocoa WebView : can I load web and local resources together in the same page?

ios - iPhone:目前适合所有 iPhone 屏幕的登录屏幕图像

iOS。使用 USB 麦克风以 96kHz 录制

objective-c - AFIncrementalStore 还在维护吗?

macos - 阴影 css 过滤器不适用于 safari 9.1

iphone - 如何将字符串对象传递给 ABNewPersonViewController.h 的名称字段?

iphone - 如何确定 iPad 上的键盘覆盖了多少模态 VC?