以编程方式修改他人的AppDelegate - 分类,子类?
我正在制作一个框架安装脚本。这个脚本需要修改用户的 AppDelegate 文件,并在 applicationDidFinishLaunching 和 applicationWillTerminate 方法的开头或结尾插入几行代码。
我考虑过一些选项:
- 解析源代码,然后在正确的位置插入代码行。(这可能很难做到,而且可能不适用于每个人的代码,几乎相当于写一个编译器……)
- 对 AppDelegate 文件进行子类化(这可能吗?)
- 使用类别??
这些选项中哪个是最好的?还有其他建议吗?
2 个回答
1
如果你真的想要让这个东西在不需要开发者干预的情况下修改 AppDelegate
,而且你可以修改 xcodeproj 和 nib 文件,但不能改动源代码,那是有办法做到的。
首先,确保你的类能够被编译,并且在 nib 文件中创建了你的类的实例。
接下来,你可以这样做:
- 定义一个
-[AHHackClass applicationDidFinishLaunching]
方法,里面做你需要的额外操作,然后调用[self originalApplicationDidFinishLaunching]
。 - 在
-[AHHackClass awakeFromNib:]
中,使用 objc 运行时的调用,把-[AHHackClass applicationDidFinishLaunching]
方法复制到应用程序代理中,命名为-[originalApplicationDidFinishLaunching]
,然后用方法交换(method swizzling)来交换这两个方法的实现。 - 对
applicationWillTerminate
也做同样的交换。
你可以查看 JRSwizzle
,它提供了一些代码,可以让方法交换变得更简单,还有 MethodSwizzling
在 CocoaDev 上的背景资料。
不过,可能有更简单的方法来实现这个:你的额外操作真的需要从应用程序代理的 applicationDidFinishLaunching
和 applicationWillTerminate
方法中调用吗?难道你不能在 awakeFromNib
中设置监听通知,然后在那里处理事情吗?
如果因为某种原因你不能这样做,那你能不能在给开发者的说明中加一句,让他们在自己的 applicationDidFinishLaunching
方法中调用你的方法呢?
0
我现在考虑的一个解决方案是:
- 添加一个新的文件 NewAppDelegate.m/h,这个文件是 AppDelegate 的子类。
- 这个子类可以实现我想要的功能,然后再调用父类的方法。
- 在 main.m 文件中,把 AppDelegate 替换成 NewAppDelegate.m/h。
这个方法看起来既简单又可靠。你觉得怎么样?这个方法适用于所有或大多数项目吗?