1. Swift / Говнокод #26534

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    import Foundation
    
    @objc protocol SomethingDoable {
        func doSomething()
    }
    
    class Inner: SomethingDoable {
        @objc func doSomething() {
            print("Inner!")
        }
    }
    
    @objc class Outer: NSObject {
    
        let inner: SomethingDoable = Inner()
    
        override func forwardingTarget(for aSelector: Selector!) -> Any? {
            return inner
        }
    }
    
    let outer = Outer()
    outer.perform(#selector(SomethingDoable.doSomething))

    Удачного дебага!

    Запостил: Desktop, 27 Марта 2020

    Комментарии (52) RSS

    • #seo

      Надеюсь, страйкер каждый раз перед тем, как посрать, семь раз вводит проверочный код.
      Ответить
    • Можно ещё круче сделать:

      @objc protocol SomethingDoable {
          init()
          func doSomething()
      }
      
      class Inner: SomethingDoable {
          required init() { }
          
          @objc func doSomething() {
              print("Inner!")
          }
      }
      
      class Outer<T>: NSObject where T: SomethingDoable {
      
          let inner: T = T.init()
      
          override func forwardingTarget(for aSelector: Selector!) -> Any? {
              return inner
          }
      }
      
      let outer = Outer<Inner>()
      Ответить
      • Не нужно лишних слов. Логика должна быть очень простая: проникнуть в заражаемый организм, адсорбироваться на клетках альвеол, проникнуть за клеточную стенку и использовать клеточные структуры как матрицу для своих копий.

        Вот и все.!
        а у Вас тут какие-то 'class Outer<T>: NSObject where T: SomethingDoable {'..

        так не годится.
        Ответить
      • показать все, что скрытоvanished
        Ответить
        • Пересылка сообщения с compile-time check. Если делать без дополнительного протокола, а пытаться вызвать селектор несуществующего метода у класса, то сделать это можно только через строковый литерал, что некрасиво. А вот так компилятор доволен.

          Но это бомба отложенного действия, как впрочем почти любое использование рантайма. Ты вызываешь селектор протокола у класса, который про этот протокол ни сном ни духом. И это говно работает.
          Ответить
    • показать все, что скрытоvanished
      Ответить
    • показать все, что скрытоvanished
      Ответить
      • forwardingTarget должен вернуть наследника NSObjectProrocol
        кстати, оно действительно напечатает "Inner", но упадет потом
        Ответить
        • показать все, что скрытоvanished
          Ответить
          • EXC_BAD_ACCESS
            в Swift классы неявно реализую протокол AnyObject и все, если нужна реализация NSObjectProrocol, то наследуем класс от NSObject явно
            Ответить
        • Оно упадёт только в песочнице и связано это, как я понимаю, с витками ранлупа. В нормальном проекте всё будет работать и не бибикать.

          В документации[1] никакого упоминания, что "forwardingTarget должен вернуть наследника NSObjectProrocol", нет.

          [1] https://developer.apple.com/documentation/objectivec/nsobject/1418855-forwardingtarget
          Ответить
    • показать все, что скрытоvanished
      Ответить
      • Не видел.

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

    Добавить комментарий