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?