【发布时间】:2017-02-09 18:31:06
【问题描述】:
我有一个用 Objective C 编写的库,作为 Cocoapod 发布。该库所做的部分工作是对添加到的任何应用程序的 AppDelegate 类进行一些调整。当该库被添加到一个简单的 Objective-C 应用程序(其中没有任何内容的单页应用程序)中时,回调方法被正确调配,每个人都很高兴。但是,当将该库添加到类似的 Swift 应用程序时,由于 AppDelegate 为 null(或 nil),因此 swizzling 会失败。
下面是库中的代码:
(注意:这个方法是从 UIResponder 的 load: 方法中调用的。)
UIResponder+MyCustomMethods.m
/**
* This class swizzles the methods needed to observe protocol methods
*/
@implementation UIResponder (WTAutomatics)
...
+ (void)swizzleAppDelegate:(SEL)original with:(SEL)replacement forProtocol:(Protocol *)protocol
{
id appDel = [[UIApplication sharedApplication] delegate];
Class appDelegate = [appDel class];
// Alternatively, we can do this. Both work the same.
// Class appDelegate = [[[UIApplication sharedApplication] delegate] class];
NSLog(@"Starting swizzle: %@", NSStringFromSelector(original));
if (!appDelegate) {
WTLog(@"Failed to swizzle because appDelegate is null.");
return;
}
if (class_conformsToProtocol(appDelegate, protocol)) {
// Do the method swizzling
...
}
}
在上面的代码中,appDelegate 的值是有效的,并且 swizzling 在任何 Objective C 应用程序中都有效。但是,当在 Swift 应用程序中运行时,appDelegate 为 null,并且 swizzle 失败。
两种语言之间的应用程序委托的初始化顺序有什么不同吗?我还缺少什么吗?
【问题讨论】:
-
这在 Obj-c 应用程序中是如何工作的? +load 应该在 main 之前调用,main 是 UIApplication 被创建和初始化的地方。
标签: ios objective-c swift appdelegate swizzling