在开发源代码项目时,我遇到了以下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,它仅说明:
因为Objective-C基于ANSI C,你可以自由地使用 使用Objective-C代码混合直接C代码。而且,你的代码 可以调用非Cocoa编程接口中定义的函数 作为/ usr / include中的BSD库接口。
没有提及C函数何时应该支持Objective-C方法。
此时我能看到的唯一好处是,调用上面的函数,而不是类方法,将跳过一些Objective-C运行时调用。在FSNData
的典型用例中,这不会给用户带来明显的性能提升(甚至可能对开发人员而言)*。
在类方法上支持C函数有什么好处(编码风格除外)?
* FSNData
用作FSNetworking库的一部分,因此我怀疑在任何应用程序的生命周期中都会有成千上万的网络操作被执行。
答案 0 :(得分:11)
简而言之,C(或C ++)实现非常有用:
在类方法上支持C函数有什么好处(编码风格除外)?
当然,你不会总是因为你不需要或不使用的东西而付出代价 - 并且记住ObjC类方法也比C函数有一些好处。因此,只需将C或C ++实现视为工具箱中的另一个工具。我发现它们非常有用,因为复杂性和项目大小增加了,它们可以用来使程序更快。做你最不可能在2015年后悔的事情;)
答案 1 :(得分:9)
您已经触及避免objc_msgSend
来电的边际效果差异。 Objective-C类方法也可以覆盖子类,因此在C中实现一个方法可以防止它在子类中被覆盖。相关地,由于运行时继承/多态,因此永远不能内联Objective-C方法,而编译器可能会内联C函数以增加性能。
当谈到避免objc_msgSend
时,一位聪明人曾告诉我,“如果objc_msgSend
的开销对你来说太大了,那么Objective-C可能是错误的工具。”