【发布时间】:2015-07-22 10:47:34
【问题描述】:
在 Objective-C 中,所有对象都可以被视为类型 id,并且几乎所有对象都继承自 NSObject。 (方块没有,但这是唯一的例外。)
因此,可以创建一个扩展所有 Objective-C 对象的 Objective-C 类别。 (忽略块)
在 Objective-C 中,我为 NSObject 创建了一个扩展,它使用关联对象来选择性地将字典附加到任何 NSObject。这使我能够实现方法setAssocValue:forKey: 和assocValueForKey:,从而可以将键/值对附加到任何NSObject。这在很多情况下都很有用。
例如,它可以将存储的属性添加到类别中。您只需编写一个 getter/setter,它使用关联的值方法来附加存储的对象,然后就可以了。
它还可以在运行时将值附加到现有系统对象。您可以将数据或代码块挂在按钮上,或者做任何您需要做的事情。
我想在 Swift 中做同样的事情。
然而,Swift 并没有像 Objective-C 那样为所有对象提供一个通用的基类。 AnyObject 和 Any 是协议。
因此,
extension AnyObject
不会编译。
我不知道在 Swift 中“附加”我的 setAssocValue:forKey: 和 assocValueForKey: 方法的位置。
我可以为我的扩展创建一个基类,但这违背了使用扩展的意义。我可以让我的基础对象成为一个 Objective-C NSObject,但这意味着我所有的对象都必须是 NSObject,而 Swift 对象默认不是 NSObject。
(顺便说一句,这个问题适用于 Mac OS 和 iOS 平台)
【问题讨论】:
-
因此我声明“几乎所有对象都继承自 NSObject”。我忘了
NSDistantObject,但确实给出了块的例子,它们是对象但不是NSObjects。 -
我认为 Swift 没有任何“扩展方法”(.NET)或“隐式”(Scala)的概念?
-
我不熟悉 C#/.NET。你能解释一下扩展方法是什么吗?
-
有效地在编译时 decomposed static wrappers 以“伪造”特定编译时类型的表达式的方法。也就是说,原始类型/类/对象本身没有被修改,但可以像添加了附加方法一样使用。我不知道 Swift 是否提供类似的东西。
-
这与 Swift 扩展或 Objective-C 类别(本主题的主题)有何不同?听起来是一样的。