在做开源项目时,我遇到了以下 C 函数声明和实现:
// FSNData.h
NSString *stringForMimeType(MimeType type);
@interface FSNData : NSObject
// All the expected objective-c property and instance method declarations
@end
// FSNData.m
#import "FSNData.h"
// where 'type' is an enum
// this does work as expected
NSString *stringForMimeType(MimeType type) {
switch (type) {
case MimeType_image_jpeg: return @"image/jpeg";
case MimeType_image_png: return @"image/png";
default:
NSLog(@"ERROR: FSNData: unknown MimeType: %d", type);
// do not return "application/octet-stream"; instead, let the recipient guess
// http://en.wikipedia.org/wiki/Internet_media_type
return nil;
}
}
@implementation
// all properties and methods defined in FSData.h implemented as expected
@end
这个例子可以很容易地重写为一个类级别的方法,没有任何问题。事实上,使用 stringFormMimeType()
仍然需要导入 FSNData
头文件。
查看the Apple docs ,它只说明:
Because Objective-C rests on a foundation of ANSI C, you can freely intermix straight C code with Objective-C code. Moreover, your code can call functions defined in non-Cocoa programmatic interfaces, such as the BSD library interfaces in /usr/include.
没有提到 C 函数何时应该支持 Objective-C 方法。
此时我能看到的唯一好处是调用上述函数,而不是类方法,一些 Objective-C 运行时调用将被跳过。在 FSNData
的典型用例中,这不会给用户(甚至可能对开发人员)带来明显的性能提升*。
与类方法相比,C 函数有什么好处(除了编码风格)?
*FSNData
用作 FSNetworking 的一部分库,所以我怀疑在任何应用程序的生命周期中都会执行成千上万的网络操作。
最佳答案
简而言之,C(或 C++)实现非常有用:
- 抽象
- 为了可重用性
- 制作大中型节目时
- 在性能关键路径中
- 对于“内部”实现
What benefit exists (other than coding style) for favouring a C function over a class method?
- ObjC 消息传递引入了间接函数调用。这些是优化器的防火墙。
- C 函数可以很容易地限制访问,而“私有(private)”ObjC 实现可能会使用 ObjC 运行时查找,或者被意外覆盖。
- 如果未引用 C 函数,则可能会从您的可执行文件中删除它们,或者将它们设为私有(private)。如果您编写可重用代码(您应该这样做),这会对您的二进制文件大小和加载时间产生巨大影响——未被引用/使用的 C 函数可能会被删除,但 ObjC 类型和方法将被保留(包括它们的所有内容)引用)。这就是为什么当您只使用 ObjC 静态库的一小部分时,您的应用程序的二进制大小可能会显着增加的原因——库中的每个 objc 类都会被保留。如果该库是 C 或 C++,那么您可以通过非常小的增长获得,因为您只需要引用的内容。用 C 和 C++ 更容易证明引用或未引用的内容。
- C 函数可以在编译期间或链接时优化阶段内联。
- 编译器和优化器能够对 C 函数进行大量优化(例如过程间优化),但对 ObjC 方法进行的优化很少,因为它们总是间接的。
- 避免 ObjC 消息分发开销(如您所述)
- 与 ObjC 对象交互时可能会出现额外的引用计数操作和自动释放池事件。
当然,您不会总是为不需要或不使用的东西付费而感到痛苦——请记住,ObjC 类方法也比 C 函数有一些好处。因此,只需将 C 或 C++ 实现视为工具箱中的另一个工具即可。随着复杂性和项目规模的增加,我发现它们非常有用,并且它们可用于使您的程序更快。只做你在 2015 年最不可能后悔的事 ;)
关于objective-c - Objective C 类方法与 C 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21763698/