Objective-C中的无状态静态方法与C函数

Objective-C中的无状态静态方法与C函数,objective-c,coding-style,static-methods,Objective C,Coding Style,Static Methods,就良好的Objective-C编码实践而言,如果我创建了一个没有状态的函数,那么最好将其作为某个类的静态方法编写,还是作为C函数编写 例如,我有一种特殊的文件路径检索方法,它在进入主NSBundle之前检查缓存目录。我目前把它作为静态方法放在一个空的Utils类下。这应该是一个C函数吗 我选择使用静态方法(目前)的原因是a)它与Objective-C语法一致,b)类帮助对方法进行分类。然而,我觉得我有点作弊,因为我可以很容易地用这些无状态静态方法填充我的Util类,最终得到一个丑陋的“shell

就良好的Objective-C编码实践而言,如果我创建了一个没有状态的函数,那么最好将其作为某个类的静态方法编写,还是作为C函数编写

例如,我有一种特殊的文件路径检索方法,它在进入主NSBundle之前检查缓存目录。我目前把它作为静态方法放在一个空的Utils类下。这应该是一个C函数吗

我选择使用静态方法(目前)的原因是a)它与Objective-C语法一致,b)类帮助对方法进行分类。然而,我觉得我有点作弊,因为我可以很容易地用这些无状态静态方法填充我的Util类,最终得到一个丑陋的“shell类”,其唯一目的就是保存它们

你用什么惯例?从某种客观标准来看,一个比另一个“好”吗?谢谢大家!

如果你能想到一个现有的类,它可能是一个好方法,你可以通过创建Objective-C类别将你的方法注入其中。这就保留了使用静态方法的两个原因,同时又不会用额外的类污染类空间

例如:

@interface NSString (MyStringCategories) 
- (NSString*) myCoolMethod;
@end

// [StringCategories.m]
#import "StringCategories.h"

@implementation NSString (MyStringCategories)
- (NSString*) myCoolMethod {
    // do cool stuff here
    return whateverYouLike;
}
@end
现在您可以将
mycolmethod
发送到任何字符串。酷


在您的特定情况下,听起来NSBundle上的方法可能是合适的体系结构。别忘了,它可以是一个类方法,所以你不需要实例化任何东西来调用你的方法。

这是一个很难回答的问题,因为对很多人来说,答案取决于他们的个人喜好和品味。我个人认为,如果您有一个函数,即它与对象无关,它没有内部状态等。pp.请让它成为一个函数,不要试图将您可能的所有内容包装到一个对象中,因为您使用的是OO语言,您可以

为了使我的回答简短,让我参考一本(国际海事组织)相当不错的书:

我知道这是C++的,但是有很多的见解可以与其他语言共享(特别是ObjuleC和ObjuleC++),特别是从“类设计和继承”的部分。在那里您会发现一个项目滴度“更喜欢编写非成员非方向函数”

一句话:“非成员非朋友函数通过最小化依赖关系来改进封装[…]它们还可以分解整体类[…],并]改进泛型[…]


我认为这一点很有道理。

如果没有类可以清晰地绑定它,那么我就使用函数。我还为这些实用程序位使用函数,因为如果不使用或引用它们,它们可以被剥离。在这方面,使用函数也很有帮助,因为链接错误比运行时错误更好(即使是在构建中意外省略了.m,或者是从另一个外部更新的方法引用的)。ObjC符号的一个问题是它们不会被剥离,因此它们自然带有大量的依赖性——所有ObjC方法和类以及所需的类别方法必须存在于最终二进制文件中。对于真正的小程序或库来说,这不是一个问题,但对于中/大型系统和库来说,它很快就会变得更重要

不需要在
@接口中声明所有内容,尤其是在大型系统中,所有这些声明都会将您的相互依赖性变成意大利面条。与方法相比,函数更快、更小,可以由编译器或在链接过程中更好地优化,如果不引用,则可以剥离

如果您需要多态性,它只是为了组织或方便而属于类,那么类或实例方法通常是更好的选择


出于同样的原因,我还最小化了声明类别方法。当您使用函数时,您可以在需要的地方轻松编写包装器方法,并充分利用这两个方面。

是的,我会尽可能经常这样做。但是,在这种情况下,我想不出一个方法——它只在缓存中找不到文件时搜索捆绑包,而且它不是典型的pathForResource:的实例方法,因此(在我看来)它不是一个理想的方法。因此,将它设为类方法。我的观点是,不能想到一个合适的现有类,难道不是想象力的失败吗?它可以是NSBundle,也可以是NSFileManager,也可以是NSString(因为它处理路径名),也可以是任何你直觉上认为合适的类。我个人认为类的目的是被实例化。不要将类用作命名空间。所以,如果你只有静态方法,你应该考虑另一种方法。例如,在WWDC2011的一个视频中,他们谈到使用类方法来避免创建共享实例。当然还有很多内置的类方法,比如UIFont的
familyNames
,它们实际上只是全局函数,可以说,它们被放入了一个合适的类中,作为对它们进行分类的一种方式。错过类方法就是错过了OOP精神的一部分。@matt我想苹果公司想了很多事情。。。依我看,单例类甚至比“静态”类更好。UIFont不是一个好例子,因为UIFont对象可以(并且需要)实例化,因为它需要IVAR。在这种情况下,静态方法很有用,因为它们提供了辅助方法的方便构造函数。但最后,您有了一个真实的UIFont实例。这里的问题不是这样的。