【问题标题】:Can I inline static class methods in Objective-C?我可以在 Objective-C 中内联静态类方法吗?
【发布时间】:2011-06-12 01:48:34
【问题描述】:

您可以像这样将函数声明为内联:

#ifdef DEBUG
void DPrintf(NSString *fmt,...);
#else
inline void DPrintf(NSString *fmt,...) {}
#endif

这样,当您不在 DEBUG 中时,该函数不会产生任何成本,因为它是经过优化和内联的。如果你想拥有相同的东西,但要使用类方法怎么办?

我的班级是这样声明的:

@interface MyClass : NSObject {

}

    + (void)DPrintf:(NSString *)format, ...;
    // Other methods of this class
@end

我想将 'DPrintf' 转换为类似于 inline 的内容,这样调用该方法就不会产生任何费用。

但我不能这样做:

inline +(void)DPrintf:(NSString *)format, ...; {}

如何为非调试编译关闭一个类的零成本静态方法?

【问题讨论】:

    标签: objective-c methods inline


    【解决方案1】:

    小心。 Objective-C 方法与 C 函数不同。编译器将 Objective-C 方法转换为 objc_msgSend() 函数调用;您无法控制方法是否内联,因为这无关紧要。您可以阅读有关 Objective-C 运行时 here (Objective-C Runtime Programming Guide)here (Objective-C Runtime Reference)here (CocoaSamurai post) 的更多信息,并且快速的 Google 搜索应该会找到更多信息。

    【讨论】:

    • 另外,请注意过早的优化。打印内容的函数上的内联标记不太可能节省很多时间,即使该函数被多次调用。内联主要只在返回非常容易计算的地方才有意义,因此函数调用开销很大。就调用的指令数量而言,涉及 printf 的任何变体都不是一件容易的事。
    • 除此之外,当今大多数现代编译器(无论是 GCC 还是 Clang)通常都知道如何识别能够自行内联运行的函数,并将它们自己标记为此​​类。众所周知,人类不擅长估计哪些函数内联运行良好,因此建议您不要管它,让编译器弄清楚(我听说过一些 C 编译器甚至会忽略您是否将函数标记为内联,所以要小心)。
    【解决方案2】:

    Objective-C 中没有静态方法。只有类方法,它们就像实例方法一样,只是它们属于一个类。这意味着,就像实例方法一样,发送到类的消息必须通过消息调度机制来确定要调用的正确方法,并且这是在运行时完成的。您可以内联对方法调度机制的调用,但如果没有目前任何 Objective-C 编译器中不存在的疯狂优化级别,仍然无法内联方法主体。

    无论如何,这是一个微优化。如果分析表明它是必要的(它几乎永远不会),那么你可以通过体操。否则,请担心应用程序中的实际性能问题。

    【讨论】:

    • 对于那些(像我一样)来自 Java 背景的人,其中类方法和静态方法是同义词,请注意,在 Objective-C 中,类方法是动态解析的——对类对象进行操作,这就是为什么它们不是“静态的”。 en.wikipedia.org/wiki/Method_(computer_programming)
    【解决方案3】:

    是的!

    您可以使用积木来完成此操作

    -(void)viewDidLoad {
    
        void(^inlineFunction)(int) = ^(int argument) {
            NSLog(@"%i", argument);
        };
            
        inlineFunction(5);//logs '5'
    
    }
    

    Apple 甚至记录了这个 here (archive),因此它不像许多网上人认为的那样是一种私人方法。

    享受吧!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-20
      • 1970-01-01
      • 1970-01-01
      • 2013-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-28
      相关资源
      最近更新 更多