以编程方式修改他人的AppDelegate - 分类,子类?

1 投票
2 回答
565 浏览
提问于 2025-04-17 15:55

我正在制作一个框架安装脚本。这个脚本需要修改用户的 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 上的背景资料。

不过,可能有更简单的方法来实现这个:你的额外操作真的需要从应用程序代理的 applicationDidFinishLaunchingapplicationWillTerminate 方法中调用吗?难道你不能在 awakeFromNib 中设置监听通知,然后在那里处理事情吗?

如果因为某种原因你不能这样做,那你能不能在给开发者的说明中加一句,让他们在自己的 applicationDidFinishLaunching 方法中调用你的方法呢?

0

我现在考虑的一个解决方案是:

  1. 添加一个新的文件 NewAppDelegate.m/h,这个文件是 AppDelegate 的子类。
  2. 这个子类可以实现我想要的功能,然后再调用父类的方法。
  3. 在 main.m 文件中,把 AppDelegate 替换成 NewAppDelegate.m/h。

这个方法看起来既简单又可靠。你觉得怎么样?这个方法适用于所有或大多数项目吗?

撰写回答