在运行时加载Objective C类有什么意义?

时间:2012-10-11 02:19:30

标签: objective-c runtime objective-c-category memory-efficient

是吗:

为了提高内存效率,不必一直将所有程序的方法存储在RAM中?如果是这样,这真的是常见问题吗?我觉得必须加载一个新方法的开销会抵消正常大小的程序的内存节省,虽然我可以看到它对于非常大的东西会有什么帮助。

为了提高灵活性?如果是这样,你能给出一个例子吗?我发现很难想到一个。

我一直试图谷歌解决这个问题的答案,似乎只找到如何使用类别的资源而不是为什么。如果你们中的任何一个人能指出我正确的方向 awesome

2 个答案:

答案 0 :(得分:5)

类别的主要原因是允许您将方法添加到您没有源代码的类,或者您不想修改源代码的类。

示例1。

我想要一种通过加载动画GIF来创建动画UIImage的方法。从逻辑上讲,这应该是UIImage类方法,但我没有UIKit框架的源代码(包含UIImage)。所以我为UIImage写了一个类别,它添加了一个名为animatedImageWithAnimatedGIFData:的类方法。您可以在my uiimage-from-animated-gif repository中找到它。

我是否必须将此方法添加到UIImage?不,我可以使它成为常规的C函数,或者我可以创建一个实用程序类(可能名为AnimatedGIFLoader)来保存该方法。但从设计的角度来看,该方法在逻辑上属于UIImage

示例2。

Apple希望能够轻松地将字符串绘制到图形上下文中。在具有GUI的程序中,NSString具有绘制方法是合理的。 Apple拥有Foundation框架的源代码(包含NSString),因此可以添加它。但是Foundation框架旨在用于各种程序,包括没有任何用户界面的程序。因此,Foundation中的类对UIKit或AppKit或Core Graphics或任何其他可以绘制图形的高级库都不了解。

相反,UIKit有一个类别可以将drawAtPoint:withFont:方法添加到NSString。 AppKit有一个类别,可将drawAtPoint:withAttributes:方法添加到NSString

AppKit和UIKit有许多其他类别可以为Foundation类添加方法。例如,UIKit在NSObjectNSIndexPathNSCoder等方面都有类别。

使用类别的另一个原因是将类的实现拆分为多个.m文件。如果您有一个大类,则可以将其某些选择器移动到一个类别中,并在单独的源文件中实现类别方法。链接器在创建可执行文件时会自动将类别合并到类中,因此没有运行时惩罚。

答案 1 :(得分:0)

动态加载类别的一个原因是有条件地这样做。我已将此用于与不同版本的操作系统兼容。

例如,较新版本的系统框架提供了一些我想要使用的不错功能。但是,我的目标是部署到早期版本的操作系统。我可以为旧版本的新功能实现(部分)替换,但我想在较新版本上使用系统代码。所以,我实现了一个提供新方法实现的类别,但我只在旧系统上加载它。我必须避免在较新版本的操作系统上加载它,因为如果我这样做,该类别将取代系统提供的方法。