通过Objective-C中的类别有条件地覆盖系统方法?

adi*_*dib 7 macos cocoa objective-c

有没有办法在系统中尚未定义方法时提供方法实现(与框架定义的方法具有完全相同的名称)?例如,方法[NSSomeClass someMethod:]仅存在于Mac OS X 10.6中,如果我的应用程序在10.5中运行,我将在类别中提供该方法的定义.但是当应用程序在10.6中运行时,我希望运行OS提供的方法.

背景:我正在创建一个针对10.5和10.6的应用程序.问题是我最近意识到该方法+[NSSortDescriptor sortDescriptorWithKey:ascending:]仅存在于10.6中,并且我的代码已经被该方法调用所困扰.我可以为它提供一个默认实现(因为这次我自己实现起来并不太困难),但是我希望每当我的应用程序在10.6上运行时都会调用"本机"实现.此外,如果我将来遇到类似的问题(更难以实现自己的方法),我可能无法摆脱提供单线代替.

这个问题模糊地类似于通过ObjC类覆盖一个方法并调用默认实现?但不同之处在于我只想在系统还没有实现时才提供实现.

谢谢.

0xc*_*ced 7

我会将+[NSSortDescriptor sortDescriptorWithKey:ascending:]一个类别编译成一个单独的包.然后在main的最开始,检查NSSortDescriptor类是否具有该sortDescriptorWithKey:ascending:方法respondsToSelector:.如果它没有实现(即你运行<10.6),那么加载捆绑包-[NSBundle loadAndReturnError:].

这样,您将在10.6上运行OS提供的方法,在10.5上运行您的实现.


smo*_*gan 4

是的,这是可能的。由于您的目标是 10.5+,我假设您正在使用 ObjC2 运行时,这使得它相当简单。

Objective -C 运行时参考包含您需要的所有方法。具体来说,您可以使用 class_getClassMethod 或 class_getInstanceMethod 来查看该方法是否已存在,然后使用 class_addMethod 将您的实现绑定到该选择器(如果该类尚不存在)。