В быстром расширении получить фактический вызывающий объект?


Скажем, мы находимся в экземпляре 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)
        }
}

Как узнать, какой объект называется расширением??

(NB, я понимаю, что вы могли бы передать его или использовать его в качестве базы :))

Можете ли вы сделать такую вещь в Swift? Вы можете узнать, кто вам звонил?

Аналогичная проблема: в Примере, не могли бы вы узнать к какому объекту относится селектор ("s" в Примере)??

2 3

2 ответа:

Обычно можно повторить трассировку стека программы, но вам нужны отладочные символы, чтобы выяснить, где живет параметр self метода, и он может даже больше нигде не находиться в оптимизированной сборке, или вызывающий объект мог быть встроен, или пострадал от какой-то другой деструктивной судьбы по прихоти оптимизатора. Таким образом, хотя можно получить аппроксимацию того, какой метод вызвал вас, невозможно получить параметр self вашего вызывающего объекта на развернутом, без символов, оптимизированная сборка.

И нет, также невозможно получить класс из селектора. Селектор-это на самом деле просто строка, которая идентифицирует имя метода, например "fixer:". Синтаксис #selector() только гарантирует, что компилятор генерирует правильное имя селектора для метода (учитывая возможные аннотации @objc) и помогает инструментам рефакторинга понять, что происходит.

Я думаю, что принцип ,согласно которому" объект-владелец управляет тем, как или если он подвергается воздействию ребенка", является одной из самых фундаментальных вещей в программировании.

Наличие механизма, который позволил бы ребенку легко отражать родительский объект, нанесло бы невообразимый ущерб нашим кодовым базам.