-3
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.");
    }

}

The Console logged:

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 indicates the manager's delegate is exsits, but
log 4 indicates(dispatch in func deal(with trouble: String) -> Void) the manager's delegate is nil, and the delegate method did not called.

The SubManager's instance object manager, the self in func deal(with trouble: String) -> Void is just the manager, but why it can't get its delegate value.

I think that the self.delegate in method func deal(with trouble: String) -> Void and in SubManager's implementation may be different In Compile time.

In Objective-C Code, whenever and wherever the self.delegate is called, the subclass's implementation is first dispatched. ()

It is a bug of swift?

mlibai
  • 31
  • 5
  • 3
    I recommend to add code snippets instead of photos. – Ahmad F Mar 13 '17 at 07:30
  • If `parent` class and `child` class both declare property with same name there would be two properties, but `child`'s one will *shadow* `parent`'s one in instances of `child` class. But if you cast `child` class instance to `parent` class instance you will get shadowed `parent`'s property. – user28434'mstep Mar 13 '17 at 07:49
  • @user28434 can not declare property in both super class and subclass with the same name in swift, so `child's one will shadow parent's one` won't happen. – mlibai Mar 13 '17 at 15:58

1 Answers1

3

Because you have a default implementation that return nil for the delegate var. Remove the useless extension protocol.

kokluch
  • 602
  • 5
  • 16