协议和子类在Swift中,self并不意味着当前的对象

时间:2017-03-13 07:28:01

标签: ios swift protocols subclassing

protocol ManagerDelegate: class {
    func manager(_ manager: ManagerProtocol, didDealWith trouble: String) -> Void
}

protocol ManagerProtocol: class {
    weak var delegate: ManagerDelegate? { get set }
}

private class Wrapper {
    weak var delegate: ManagerDelegate?
    static var key = "key";
}

extension ManagerProtocol {
    private var wrapper: Wrapper {
        if let wrapper = objc_getAssociatedObject(self, &Wrapper.key) as? Wrapper {
            return wrapper;
        }
        let wrapper = Wrapper();
        objc_setAssociatedObject(self, &Wrapper.key, wrapper, .OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        return wrapper;
    }

    weak var delegate: ManagerDelegate? {
        get {
            return self.wrapper.delegate;
        }
        set {
            self.wrapper.delegate = newValue;
        }
    }
}

class Manager: ManagerProtocol {
    func deal(with trouble: String) -> Void {
        print("2. Manager is dealing `\(trouble)` ")
        DispatchQueue.main.async {
            self.delegate?.manager(self, didDealWith: trouble);
            print("4. Manager did notice `\(self.delegate)` that the `\(trouble)` had been dealed.");
        }
    }
}

protocol SubManagerDelegate: ManagerDelegate {

}

class SubManager: Manager {
    weak var delegate: SubManagerDelegate?
}


class ViewController: UIViewController, SubManagerDelegate {

    let manager = SubManager();

    override func viewDidLoad() {
        super.viewDidLoad()
        self.manager.delegate = self;

        self.get(trouble: "trouble");
    }

    func get(trouble: String) -> Void {
        print("1. Controller get a `\(trouble)`.");
        self.manager.deal(with: trouble);
        print("3. Controller did send the `\(trouble)` to Manager whose delegate is `\(self.manager.delegate)`");
    }

    func manager(_ manager: ManagerProtocol, didDealWith trouble: String) {
        print("5. Controller did recevie Manager's message that the `\(trouble)` had been dealed.");
    }

}

控制台已记录:

1. Controller get a `trouble`.
2. Manager is dealing `trouble` 
3. Controller did send the `trouble` to Manager whose delegate is `Optional(<SwiftTest.ViewController: 0x7f9abcc03590>)`
4. Manager did notice `nil` that the `trouble` had been dealed.

log 3表示经理的代表是exsits,但是 log 4表示(在func deal(with trouble: String) -> Void中发送)管理器的委托是nil,并且没有调用委托方法。

SubManager的实例对象managerself中的func deal(with trouble: String) -> Void只是manager,但为什么它无法获得delegate值。< / p>

我认为方法self.delegatefunc deal(with trouble: String) -> Void的实现中的SubManager在编译时可能会有所不同。

Objective-C代码中,无论何时何地调用self.delegate,都会首先调度子类的实现。 ()

这是一个快速的错误?

1 个答案:

答案 0 :(得分:3)

因为您有一个默认实现,它为委托var返回nil。删除无用的扩展协议。