Objective c 为什么clang允许在没有@实现的情况下使用@接口?它有什么作用?

Objective c 为什么clang允许在没有@实现的情况下使用@接口?它有什么作用?,objective-c,clang,objective-c-category,Objective C,Clang,Objective C Category,我有以下课程/协议: @interface Super @end @implementation Super @end @interface Sub1 @end @implementation Sub1 @end @interface Sub2 @end @implementation Sub2 @end @protocol FooProtocol - (void) foo; @end @interface Sub1 (FooCategory) <FooProtocol> @end

我有以下课程/协议:

@interface Super
@end
@implementation Super
@end
@interface Sub1
@end
@implementation Sub1
@end
@interface Sub2
@end
@implementation Sub2
@end

@protocol FooProtocol
- (void) foo;
@end
@interface Sub1 (FooCategory) <FooProtocol>
@end
@implementation Sub1 (FooCategory)
- (void) foo {}
@end
@interface Sub2 (FooCategory) <FooProtocol>
@end
@implementation Sub2 (FooCategory)
- (void) foo {}
@end
@interface Super (FooCategory) <FooProtocol>
@end
// Notice that there is no @implementation Super (FooCategory)
Sub1
Sub2
Super
仅有的两个子类。我本质上希望在category方法中使用多态性。如果我为
Super
指定了
@接口
,但没有提供
@实现
,则clang不会给我任何警告/错误

这真的是一个糟糕的黑客吗


潜在的不利因素是什么

Objective-C没有“抽象方法”的概念。当你需要一个,你几乎不得不选择,但使用一些黑客


尽管我建议您将该方法放在
Super
中,并在调用时抛出异常。

Objective-C没有“抽象方法”的概念。当你需要一个,你几乎不得不选择,但使用一些黑客

尽管我建议您将该方法放在
Super
中,并在调用时抛出异常。

(最初来自对zneak答案的评论)

如中所述,类别中的方法在运行时确实会成为目标类的一部分,这就是为什么对现有方法进行攻击会很危险,以及为什么实现同一方法的多个类别的行为是未定义的。一旦安装了该方法,它实际上与最初的方法没有什么不同:

类别方法可以做在类本身中定义的方法可以做的任何事情。在运行时,没有区别。与其他方法一样,类别添加到类中的方法由类的所有子类继承

Super
上有一个category,在它的子类上有一个categories实现相同的方法是可以的,它的工作原理与类本身的工作原理完全相同。(尽管我建议遵循zneak的建议,在
Super
上实现存根方法,以便在意外调用时帮助调试。)

(最初来自于对zneak答案的评论。)

如中所述,类别中的方法在运行时确实会成为目标类的一部分,这就是为什么对现有方法进行攻击会很危险,以及为什么实现同一方法的多个类别的行为是未定义的。一旦安装了该方法,它实际上与最初的方法没有什么不同:

类别方法可以做在类本身中定义的方法可以做的任何事情。在运行时,没有区别。与其他方法一样,类别添加到类中的方法由类的所有子类继承


Super
上有一个category,在它的子类上有一个categories实现相同的方法是可以的,它的工作原理与类本身的工作原理完全相同。(尽管我建议遵循zneak的建议,在
Super
上实现存根方法,以便在意外调用时帮助调试。)

您发布的代码开头有一个
@implementation Super
。抱歉,我的评论应该是:
//注意没有@implementation Super(FooCategory)
您发布的代码开头有一个
@implementation Super
。很抱歉,我的评论应该是:
//注意没有@implementation Super(FooCategory)
我意识到Objective-C没有抽象方法。我认为Objective-C不允许你用类别覆盖方法。苹果关于类别[1]的文档说,“可以添加到类中的类别数量没有限制,但每个类别名称必须不同,并且每个类别都应该声明和定义一组不同的方法。”[1]我不能将该方法放在
Super
中。我不控制
Super
的源代码,所以我需要该方法存在于
Super
@HeathBorders上的一个类别中,那么我相当肯定这是可以的。我见过的许多框架都在
NSObject
上声明类别,给它们提供空实现,然后让类重写这些类e方法。这是不同的。用子类重写category方法是可以的。用category重写任何方法都不是一个好主意,因为缺少
super
定义[1]。明确不支持用另一个category重写category方法(基于我上面的链接),但我想知道我是否被允许在子类中这样做。[1]@JustinSpahr Summers感谢您的输入。如果您将其表述为一个答案(最好带有指向文档和/或苹果电子邮件的链接)我会把它标记为正确的。我意识到Objective-C没有抽象方法。我认为Objective-C不允许你用类别覆盖方法。苹果关于类别的文档[1]说,“可以添加到类中的类别数量没有限制,但每个类别名称必须不同,并且每个类别都应该声明和定义不同的方法集。“[1]我不能将该方法放在
Super
中。我不控制
Super
的源代码,所以我需要该方法存在于
Super
@HeathBorders上的一个类别中,那么我相当肯定这是可以的。我见过的许多框架都在
NSObject
上声明类别,给它们提供空实现,然后让类重写这些类e方法。这是不同的。用子类重写category方法是可以的。用category重写任何方法都不是一个好主意,因为缺少
super
定义[1]。明确不支持用另一个category重写category方法(基于我上面的链接),但我想知道我是否被允许在子类中这样做。[1]@JustinSpahr Summers感谢您的输入。如果您将其表述为一个答案(最好带有指向文档和/或苹果电子邮件的链接),我会将其标记为正确。
void callFoo(NSArray *supers) {
  for (Super *theSuper in supers) {
    [theSuper foo];
  }
}