【问题标题】:Objective-C: my class with static methods "does not implement methodSignatureForSelector: -- trouble ahead"Objective-C:我的带有静态方法的类“没有实现 methodSignatureForSelector:——前面的麻烦”
【发布时间】:2011-03-31 19:04:53
【问题描述】:

我有一个只有静态方法的实用程序类,所以它不是从 NSObject 继承的(不需要吧?)

编译时完全没有警告。

在 iPhone 模拟器上运行时出现问题。它崩溃并发出警告“不实现 methodSignatureForSelector: -- 前面的麻烦” 好吧,我喜欢“前面有问题”的东西,我从来没有听过调试器告诉我有“前面有问题”。 但我不喜欢的是错误本身......为什么当我明确调用静态方法时,它期望我在类中实现methodSignatureForSelector? (+)

谢谢! 丹尼尔

【问题讨论】:

  • NSObject 继承不会对程序大小或性能产生任何明显的影响。 继承会让你更痛苦。

标签: objective-c methods static


【解决方案1】:

这不是 Cocoa 中的惯用模式。我强烈建议您重新考虑您的设计。这不是 Java 或 C++。一方面,甚至没有“静态方法”之类的东西——它们是类方法,类本身就是一个对象。

拥有一个不是 NSObject 子类的类也很奇怪(“不需要”不是偏离默认行为的一个非常合理的原因),而拥有一个只有类方法的类更奇怪。该类可能应该是一个单例或者被消除,并且它的方法变成了函数,这取决于它是否需要保持状态。

至于你崩溃的确切原因,如果没有看到你的代码就很难说。该警告本身不应使您的程序崩溃。您确实需要有一些+initialize 的实现,即使它什么也不做,因为运行时会将该消息发送到每个接收消息的类。这可能就是错误出现的地方——您发送一条消息,运行时尝试发送initialize,您的类没有响应,运行时尝试调用转发机制但不能。

【讨论】:

    【解决方案2】:

    感谢您的回答!

    关于“静态”与“类方法”,AFAIK 这只是命名,没有真正的区别。像“函数/方法”和“消息”。

    但是,这不一定是“不正确”的设计。 首先你必须记住,ObjC 没有命名空间,所以给事物排序的唯一方法是类。因为如果两个函数的名字发生冲突,编译器会大声喊叫。 有时有些函数是“实用程序”函数,可以在其他对象上工作,或者进行某些计算,这些函数不能直接与某个对象相关来管理它们,它们也不应该,因为这只会产生不必要的开销。

    作为一个非常有经验的 C/C++/Asm/Others 程序员,在使用 ObjC 编程时,出于性能原因,我倾向于总是自己释放内存。 出于同样的原因,我不想在不需要的地方产生任何开销。而且 ObjC 的开销很大。

    文档也没有说我必须从 NSObject 继承,它说我应该在我希望它由框架正确管理时。

    但据我了解,不需要任何管理,这些函数应该只是包装在类名命名空间中的函数。

    关于 +initialize - 只有当类继承自 NSObject 时才能被覆盖。所以最初的问题仍然存在——如果我不想要它的任何服务,为什么要从 NSObject 继承?我不需要分配或初始化类,因为我与它的实例无关!

    在 ObjC 中还有一个奇怪的事情是你可以覆盖一个类方法?!

    【讨论】:

    • 是的,“静态”和“类”方法之间存在真正的区别。 “静态”方法是函数的语法糖,但 Objective-C 类方法是发送到类对象的真实动态调度方法。这就是为什么,正如您自己所指出的,您可以覆盖它。这也意味着调用类方法会产生开销,因此根据您自己的逻辑,您不应该不必要地使用它们。
    • 方法和消息也是不同的概念。 Objective-C 中的消息表达式不直接调用方法;它通过一种可以定制的机制(例如,通过转发或动态添加方法)来调度它。方法和消息之间通常存在一对一的关系,但并非总是如此。
    • Objective-C 确实有类。它可能没有其他面向对象语言中的静态方法调用绑定,但它确实有类,方法和实例也有方法。 isa 和其他类似的东西只是实现细节;你不应该自己使用它们。我认为您不应该这么快就放弃与您习惯的语言不同的语言。仅仅因为它是动态调度而不是静态绑定并不意味着它不是 OOP。
    • 至少可以准确地说 Objective-C(尤其是它的动态一切方法)是面向对象的,但 C++ 和 Java 不是。如果你不相信我,问问发明这个词的艾伦凯。 :-)
    • Daniel:Stack Overflow 不是留言板。与其创建新的答案来进行对话,不如修改您的问题或用评论回复答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 2011-06-01
    • 2011-02-23
    相关资源
    最近更新 更多