Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 目标C类方法与C函数_Objective C_C_Function_Class Method - Fatal编程技术网

Objective c 目标C类方法与C函数

Objective c 目标C类方法与C函数,objective-c,c,function,class-method,Objective C,C,Function,Class Method,在从事开源项目时,我遇到了以下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 e

在从事开源项目时,我遇到了以下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()
sill仍然需要导入
fsnda
头文件

看一看,它只指出:

因为Objy-C建立在ANSI C的基础上,您可以自由地 混合直接C代码和目标C代码。此外,您的代码 可以调用非Cocoa编程接口中定义的函数,例如 作为/usr/include中的BSD库接口

没有提到什么时候C函数应该支持Objective-C方法

在这一点上,我能看到的唯一好处是,调用上述函数(而不是类方法)将跳过某些Objective-C运行时调用。在
fsnda
的典型用例中,这不会显著提高用户(甚至可能是开发人员)的性能

C函数优于类方法有什么好处(除了编码风格)


*
fsnda
被用作库的一部分,因此我怀疑在任何应用程序的生命周期中都会有成千上万的网络操作被执行。

您已经提到了避免调用
objc\u msgSend
的边际性能差异。Objective-C类方法也会在子类中被重写,因此在C中实现方法将防止它在子类中被重写。与此相关的是,由于运行时继承/多态性,Objective-C方法永远不能内联,而C函数可能由编译器内联以提高性能

当谈到避免使用Objective-C时,一位智者曾经告诉我,“如果Objective-C的开销对您来说太大,那么Objective-C可能是一个错误的工具。”

简而言之,C(或C++)实现非常有用:

  • 抽象的
  • 可重用性
  • 在制作大中型节目时,
  • 在性能关键路径中
  • 用于“内部”实现
C函数优于类方法有什么好处(除了编码风格)

  • ObjC消息传递引入了间接函数调用。这些是用于优化器的防火墙
  • C函数可以很容易地限制访问,而“私有”ObjC实现可以使用ObjC运行时查找,或者意外地被重写
  • 如果未被引用,C函数可能会从可执行文件中删除,或者它们可能是私有的。如果您编写可重用代码(您应该这样做),这可能会对二进制大小和加载时间产生巨大影响——未引用/使用的C函数可能会被删除,但ObjC类型和方法将被保留(包括它们引用的所有内容)。这就是为什么当您只使用ObjC静态库的一小部分时,应用程序的二进制大小可能会显著增加——库中的每个ObjC类都会保留下来。如果该库是C或C++,那么你可以通过非常小的增长来获得,因为你只需要引用的内容。引用或引用的东西更容易用C和C++来证明。
  • C函数可以在编译或链接时间优化阶段内联
  • 编译器和优化器能够使用C函数进行大量优化(例如,过程间优化),但使用ObjC方法的优化很少,因为它们总是间接的
  • 避免ObjC消息调度开销(如您所述)
  • 与ObjC对象交互时,可能会发生其他引用计数操作和自动释放池活动

当然,您不会总是为不需要或不使用的东西付费——而且请记住,ObjC类方法也比C函数有一些好处。所以,只需将C或C++实现作为工具箱中的另一个工具。随着复杂性和项目规模的增加,我发现它们非常有用,它们可以用来使程序更快。做你在2015年最不可能后悔的事;)

风格、程序结构(明确地将方法与类相关联)和少量(非常弱的)访问控制是我所能想到的。(但我看到@ipmcc提到了继承,还有一些东西。)我更喜欢类方法,因为Objective-C方法提供命名参数,而C函数提供命名参数not@onmyway133我特别尝试远离个人偏好(即,除了编码风格)还有一个技术原因。@MikeD这不是个人偏好,这是因为
名称参数
,这使得它更清晰了。我认为@ipmcc的答案也有很有价值的信息。你能给我一个关于函数如何以及何时被剥离的链接吗?@MikeD
man strip
将是一个介绍。在不同阶段(例如编译、链接)与优化和适当的死代码消除(或无法访问的代码)结合使用,允许工具识别哪些是引用的,哪些不是引用的,或者程序无法访问的。这对于C和C++是有用的,但是不适用于Objc符号(以及它们引用的),因为您有能力通过运行时动态地引用它们(例如,<代码> NScReasObSncs<代码> >代码> NSnestRoopOfStult >,因此所有的都默认保存,因为XCODER代表您添加了必要的标志。(续)@MikeD如果在外部调用C函数(如果在任何情况下都内联,则可能会将其删除),或者如果您通过地址引用它(例如,将其作为函数指针传递),则会“引用”C函数。如果工具链意识到您仅从无法访问的代码调用它,那么它也可能被消除。我真的要改写那一段,谢谢。这帮了不少忙。