使用 NSBundle -classNamed 按字符串检索 Class:在 iOS10 中失败

Retrieving a Class by String using NSBundle -classNamed: fails in iOS10

我在 iOS 10 上发现了问题,其中未加载具有字符串生成类名的 viewcontroller。该问题发生在 iPad Air 2 上,当用户第二次启动该应用程序时(在用力关闭后)。

在带有 Xcode 8 的模拟器中,错误是可重现的。似乎无法实例化 viewcontroller 并且此代码不再有效。这样对吗?

Class controllerClass = [[NSBundle mainBundle] classNamed:className];

解决方案是使用简单的开关盒结构来创建控制器。它需要更多的代码行,但它是更安全的代码。

我找到了一个使用底层 Objective-C 函数 objc_getClass() 并忽略现在(自 iOS10?)错误的解决方法NSBundle 的方法。由于此函数与 [MyClass class] 的功能相同,因此它应该不会失败。

我的应用程序的旧版本(iOS8 和更早版本)使用此代码似乎也无法在新硬件上运行。看起来设备越快,该方法就越有可能失败。对我来说,iOS 模拟器的失败率约为 50%。

    id objc_getClass(const char *name); // define the function signature without importing it
    Class cls = objc_getClass([s cStringUsingEncoding:NSASCIIStringEncoding]);
    NSAssert(cls != nil, @"classNamed: %@ returned nil!", s);

参考资料