在 Swift 扩展中,获取实际调用对象?

In a Swift extension, get the actual calling object?

假设我们在 SomeClass 的一个实例中,考虑这个简单的调用

NSNotificationCenter.defaultCenter().addObserver(
 self,
 selector: #selector(SomeClass.fixer(_:)),
 name:"FixerNote",
 object:nil)

假设我们决定做一个扩展来节省打字,它看起来像这样......

"FixerNote".does( #selector(SomeClass.fixer(_:)) )

这是分机...

public extension String
    {
    func does(s:Selector)
        {
        NSNotificationCenter.defaultCenter().addObserver
           .. here, you need the actual SomeClass that called us .. ,
            selector: s,
            name:self,
            object:nil)
        }
}

如何知道哪个对象调用了扩展?

(注意,我知道你可以传入它或将其用作基础 :))

你能在Swift做这样的事吗?你能查出是谁打给你的吗?

一个类似的问题:在例子中,你能找出一个选择器(例子中的"s")属于什么对象吗??

通常可以迭代程序的堆栈跟踪,但您需要调试符号来找出方法的 self 参数所在的位置,并且在优化构建中它甚至可能不再存在于任何地方,或者调用者可能已经被内联,或者在优化器的心血来潮下遭受了其他一些破坏性的命运。因此,虽然可以大致了解调用您的方法,但无法在已部署、无符号、优化的构建中获取调用方的 self 参数。

不,也不可能从选择器中得到 class。选择器实际上只是一个标识方法名称的字符串,如 "fixer:"。 #selector() 语法仅确保编译器为方法生成正确的选择器名称(考虑最终的 @objc 注释)并帮助重构工具了解正在发生的事情。

我认为"owner object is in control of how or if it is exposed to child"的原理是编程中最基本的东西之一。

拥有一种可以轻松让子对象反映父对象的机制会对我们的代码库造成难以想象的破坏。