阅读时花点时间。
将委托视为符合协议的id<ProtocolName>
“指向另一个对象的指针”。
@protocol ObjectiveCDelegate <NSObject>
@optional
- (void)delegateMethod:(NSInteger)index
view:(nonnull NSString *)view
action:(nonnull NSString *)action
dictionary:(nonnull NSDictionary<NSString *, id> *)dictionary;
@end
通常你@interface ClassName : NSObject
想要使用委托的应该有一个属性来保持它或设置它nil
(可为空),这意味着你为什么想要它weak。
@property (nonatomic, weak) id<ObjectiveCDelegate> delegate;
并且将成为您的委托的类(对象)必须符合此协议,因此您必须像以前一样在其接口中声明它。在完全美丽看起来像..
@interface ObjectiveCConformingClass : SuperClass <ObjectiveCDelegate>
@property (nonatomic, weak) id<ObjectiveCDelegate> delegate;
-(void)invokeDelegate; //for testing.
@end
因为上面的协议有可选的方法声明,所以当你没有实现它时它不会抛出警告。为避免在使用ClassName
(object) 的类中使用委托时遇到麻烦,您需要检查委托属性是否不存在nil
并且可以响应所需的方法名称。
@implementation ObjectiveCConformingClass
-(void)delegateMethod:(NSInteger)index view:(NSString *)view action:(NSString *)action dictionary:(NSDictionary<NSString *,id> *)dictionary {
NSLog(@"original objc delegateMethod, called from %@", view);
}
-(void)invokeDelegate {
if (_delegate) {
// you can double check if the delegate is really an id<ProtocolName>
if ([_delegate conformsToProtocol:@protocol(ObjectiveCDelegate)]) {
// well you don't know if delegateMethod was implemented, it was optional
// so you have to check,
// indeed it's implemented above, but it is safe this way.
if ([_delegate respondsToSelector:@selector(delegateMethod:view:action:dictionary:)]) {
//now you can call it safely
[_delegate delegateMethod:0 view:@"original ObjectiveCConformingClass" action:@"a" dictionary:@{@"key":@"value"}];
}
}
} else {
NSLog(@"original ObjectiveCConformingClass delegate is nil");
}
}
@end
到目前为止它在objective-c中工作
现在,即使在扩展程序中,您也可以快速使用委托
extension ObjectiveCConformingClass {
func extensionMethod() {
if ((delegate) != nil) {
if ((delegate?.responds(to: #selector(delegateMethod(_:view:action:dictionary:))))!) {
delegate?.delegateMethod?(1,view: "extension ObjectiveCConformingClass",action: "world",dictionary: ["foo":"bar"])
}
} else {
print("extension ObjectiveCConformingClass: delegate is nil")
}
}
// following will make you extreme trouble..
// see the missing _ so this is a different method then the objc variant
// its selector is #selector(delegateMethod(index:view:action:dictionary:)
func delegateMethod(index: Int, view: String, action: String, dictionary: [String : Any]) {
print("swift extension func delegateMethod, called from",view)
}
// #selector() is heavily confused what method to select when uncommented
// because selector is #selector(delegateMethod(_:view:action:dictionary:)
// which is declared in objc and can not be directly extended in swift
//func delegateMethod(_ index: Int, view: String, action: String, dictionary: [String : Any]) {
// print("swift extension func delegateMethod, called from",view)
//}
}
让我们检查 swift 扩展在子类化时是否正常工作。
class ClassOtherName : ObjectiveCConformingClass {
func subclassMethod() {
if (delegate != nil) {
// you still don't know if the method was implemented, so check
if ((delegate?.responds(to: #selector(delegateMethod(_:view:action:dictionary:))))!) {
delegate?.delegateMethod?(1, view:"subclass ClassOtherName", action: "action", dictionary: ["key" : "value"])
} else {
print("delegate seems not conforming to protocol")
}
} else {
print("subclass ClassOtherName delegate is nil")
}
}
// of course you can override in subclasses, even if this was a super protocol method
// see the difference.. _ as argument used here
// because Overriding non-@objc declarations from extensions is not supported
override func delegateMethod(_ index: Int, view: String, action: String, dictionary: [String : Any]) {
print("override func delegateMethod, called from",view)
}
}
让我们测试
let a = ObjectiveCConformingClass() //extended version
a.extensionMethod() // extension ObjectiveCConformingClass: delegate is nil
//a.subclassMethod() // does not exist in ObjectiveCConformingClass
a.invokeDelegate() // original ObjectiveCConformingClass delegate is nil
let o = ClassOtherName() // subclassed version of extension
o.delegate = a
o.extensionMethod() // original objc delegateMethod, called from extension ObjectiveCConformingClass
o.subclassMethod() // original objc delegateMethod, called from subclass ClassOtherName
o.invokeDelegate() // original objc delegateMethod, called from original ObjectiveCConformingClass
o.delegate = nil
o.extensionMethod() // extension ObjectiveCConformingClass: delegate is nil
o.subclassMethod() // subclass ClassOtherName delegate is nil
o.invokeDelegate() // original ObjectiveCConformingClass delegate is nil
o.delegate = o //aka o == self
o.extensionMethod() // override func delegateMethod, called from extension ObjectiveCConformingClass
o.subclassMethod() // override func delegateMethod, called from subclass ClassOtherName
o.invokeDelegate() // override func delegateMethod, called from original ObjectiveCConformingClass
希望这不会太令人困惑,但是您会看到谁在调用谁以及调用了什么。