Objective-C分类和Mixins的比较

16

Objective-C 中类别的概念是否与 Mixin 的概念相似?如果是,它们有什么相似之处?如果不是,它们有什么不同之处?

4个回答

17

据我所知:

Mixins

  • 组合的语法糖
  • 由类的开发者添加,而非用户
  • 可被多个类重复使用
  • 可添加实例变量
  • 在Objective-C中可以使用转发来实现

Categories

  • 类似于其他语言中的扩展方法(extension methods)
  • 通常由类的用户而非开发者添加
  • 只能被一个类及其子类使用
  • 无法添加实例变量

在某些编程语言(如Ruby)中,mixin(混入)不允许使用实例变量。 - Casebash
2
你可以从 Ruby mixins 中使用实例变量。 - jedediah
你不能添加实例变量,但可以做类似的事情:http://oleb.net/blog/2011/05/faking-ivars-in-objc-categories-with-associative-references/ - leftspin

7
请注意,答案是否定的 - 它们不是相同的。
John Calsbeek在接受的答案中概述了它们之间的区别,但我认为关键区别在于Mixin可以在不同的类中使用,而分类始终只扩展一个类 - 他们在定义中声明的类。
这是关键区别,因为它意味着这两个功能的用例完全不同。另一种看待它的方法是,如果你从Ruby转到Objective-C并且想念mixin,那么你在分类中找不到任何乐趣。
mixin的用例是,在几个没有共同超类的类中重复使用某些代码 - 方法和实例变量。您无法使用分类完成此操作。
Mixin实际上是"多重继承",这种类型在Objective-C中找不到。 Objective-C中最接近的东西是协议,就像Java中最接近的东西是接口,但它们既没有实例变量也没有方法体(在Objective-C或Java中)。因此,通常需要创建辅助类或将代码放在超类中。
Objective-C分类的用例是,您想向现有类添加方法 - 即使是系统或库类。

我认为Mixins更强大,但由于这是无法比较的事情,所以没有意义。

准确地说:

  • Ruby版本的Categories与Mixins等效,只需重新打开要扩展的类并扩展它即可。(您可以在Ruby中的任何地方执行此操作,并且它与Categories基本相同)

  • 我不确定Objective-C版本的Mixins等效是什么-有人知道吗?

[更新] 经过更深入的搜索,发现Objective-C没有Mixins的等效物,但是富有创造力的Vladimir Mitrovic创建了一个库,可以有效地实现它。 https://github.com/vl4dimir/ObjectiveMixin

我对是否使用它持有两种看法:有时,如果您使用的语言不支持某些功能,则使用它可能比与其作斗争或尝试从其他语言导入您喜爱的功能更容易。 (“如果您不能使用自己喜欢的编程语言,请喜欢您正在使用的那个”)。

再说,也许这只是我有点自大。整个面向切面编程运动多年来一直在为Java添加功能(但我要补充的是,在JBoss之外几乎没有获得太多关注)。无论如何,弗拉基米尔在他的例子中使用忍者神龟赢得了额外的赞誉。
另一方面,作为一个相对的Objective-C新手,我发现在我找到的所有网页示例代码中,分类似乎被过度使用。当在系统类中添加静态帮助方法时,常见做法是使用分类,而这些方法将很容易地添加到您的项目中的帮助类中,并且风险较小,可以避免在更新系统类或导入其他人的带有其自己的这些类别的库时出现错误。一个常见的例子是将新的静态颜色方法添加到UIColor中。为什么不将它们添加到本地类中呢?
我看到分类的一个真正好用的用途是添加方法,不是添加到系统类中,而是添加到生成的类中。因此,当您从核心数据对象模型生成类时,并且您想要添加新的构造函数或其他真正属于模型类的方法时,您可以使用分类来实现,使您可以安全地重新生成模型类如果您更改了模型,而不会丢失您的工作。
总之: - 忘记将类别作为mixin的解决方案 - 类别对于核心数据很好,但在其他情况下被过度使用和高估

这个答案就像一块红茎大黄派一样令人满意! - Jonah

4

据我所知,类别是为特定类定义的,您不能创建一个类别并将其实现的方法添加到几个类中。


2

使用mixin,您可以从基类和mixin派生出一个新类,然后实例化这个新类以利用它。

使用category,您实际上是直接添加到基类中,因此该基类的所有实例都可以访问类别提供的功能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接