在objective-c中,我们有一个-forwardInvocation:可以像这样使用:
-(void)forwardInvocation:(NSInvocation*) anInvocation{
BOOL didForward = NO;
//iterate over our proxied objects
for(id proxyObject in self.proxyObjects){
//invoke the with the proxy object if it can handle the selector
if ([proxyObject respondsToSelector:[anInvocation selector]]){
didForward = YES;
[anInvocation invokeWithTarget: proxyObject];
}
}
//if we did not forward the invocation, then call super
if(!didForward){
[super forwardInvocation: anInvocation];
}
}
Run Code Online (Sandbox Code Playgroud)
当你有一组所有需要相同消息的具体类时,这很有用.例如,如果您要实现多个分析平台,每个平台都需要相同的消息,但会以不同的方式处理它们.
鉴于我们对语言的了解,让我们快速做到这一点.这开始很简单:
func doSomething1(){
for proxyObject in proxyObjects{
proxyObject.doSomething1()
}
}
Run Code Online (Sandbox Code Playgroud)
但后来变得重复:
func doSomething2(){
for proxyObject in proxyObjects{
proxyObject.doSomething2()
}
}
func doSomething3(){
for proxyObject in proxyObjects{
proxyObject.doSomething3()
}
}
func doSomething4(){
for proxyObject in proxyObjects{
proxyObject.doSomething4()
}
}
....And on and on
Run Code Online (Sandbox Code Playgroud)
我知道我可以在swift中使用NSObject,但那只是混合在我们需要它的objective-c中.什么是一种更有效,更简洁的方式来处理纯粹的快速?
Swift 的构建就是为了远离这种设计模式。没有像 ObjC 这样的动态消息传递。每个方法在编译时都必须是已知的。纯 Swift 中没有真正的替代品。然而,我们可以通过使用 Swift 的闭包来模拟(在有限的程度上)ObjC 运行时所做的事情:
typealias MyAction = () -> Void
enum ValidActions {
case Hello
case Goodbye
}
protocol MyProxyProtocol {
var actions : Dictionary<ValidActions, MyAction> { get }
}
private class Concrete1 : MyProxyProtocol {
var actions = Dictionary<ValidActions, MyAction>()
init() {
self.actions[.Hello] = helloWorld
self.actions[.Goodbye] = goodbyeWorld
}
func helloWorld() -> Void {
print("Hello world from concrete 1")
}
func goodbyeWorld() -> Void {
print("Goodbye world from concrete 1")
}
}
private class Concrete2 : MyProxyProtocol {
var actions = Dictionary<ValidActions, MyAction>()
init() {
self.actions[.Hello] = hello
}
func hello() -> Void {
print("Hi from concrete 2")
}
}
public class AbstractClass {
var proxyObjects = [MyProxyProtocol]()
init() {
self.proxyObjects.append(Concrete1())
self.proxyObjects.append(Concrete2())
}
func performAction(action : ValidActions) {
for proxy in self.proxyObjects {
if let f = proxy.actions[action] {
f()
}
}
}
}
let x = AbstractClass()
x.performAction(.Hello) // Both concrete classes will do this
x.performAction(.Goodbye) // Only the first one will do this
Run Code Online (Sandbox Code Playgroud)
每个具体类都公开它可以通过字典处理的操作actions。处理它们的函数作为闭包存储在内部。
| 归档时间: |
|
| 查看次数: |
713 次 |
| 最近记录: |