Swift:在初始化程序中将func作为参数传递

时间:2015-07-20 03:36:52

标签: swift events parameters func

**更新以反映建议的代码和更详细的解释**

尝试使用turorial here来完成以下操作,因为我需要子类实例最终将功能委托给父类:

  1. 对SKNode进行子类化,以便它可以执行以下操作:
    一个。拥有SKSpriteNode类型的属性
    湾有一个属性将接受回调/事件处理程序func
       C。此属性将在初始化时保存提供的回调函数    d。此属性将“引发”一个事件(使用提供的回调函数,它将是此实例的func父对象)
  2. 但是,'/ * ... * /'之间的原始代码给出了以下错误消息:

    Cannot find an initializer for type 'ClickableSKSpriteNode' that accepts an argument list of type '(imageName: String, event: (String, string2: String) -> ())'
    

    关于这个原始代码,我可能没有一个带有“string”的初始化器,(string,string) - >()“,但我确实有一个初始化器,它接受”string,Event<(String,String )>“据我所知,它应该采用类型(String,String)的函数 - >()作为它的替代。(我对这种工作最有可能的理解是我的假设......我我来自ac#background)

    在下面的@rikkigibson(非注释代码)建议进行更改后,我收到了一个不同的错误(抱歉,此时此处没有代码)。

    任何人都有关于如何更改此代码以完成我正在尝试做的事情的任何指导?

    有问题的代码如下:

    * EVENT-RELATED CODE *
    
    public class Event<T> {
    
        public typealias EventHandler = T -> ()
    
        private var eventHandlers = [Invocable]()
    
        public func raise(data: T) {
            for handler in self.eventHandlers {
                handler.invoke(data)
            }
        }
    
        public func addHandler<U: AnyObject>(target: U, handler: (U) -> EventHandler) -> Disposable
        {
                let wrapper = EventHandlerWrapper(target: target, handler: handler, event: self)
                eventHandlers.append(wrapper)
                return wrapper
        }
    }
    
    
    private protocol Invocable: class {
        func invoke(data: Any)
    }
    
    private class EventHandlerWrapper<T: AnyObject, U>: Invocable, Disposable {
        weak var target: T?
        let handler: T -> U -> ()
        let event: Event<U>
    
        init(target: T?, handler: T -> U -> (), event: Event<U>) {
            self.target = target
            self.handler = handler
            self.event = event;
        }
    
        func invoke(data: Any) -> () {
            if let t = target {
                handler(t)(data as! U)
            }
        }
    
        func dispose() {
            event.eventHandlers = event.eventHandlers.filter { $0 !== self }
        }
    }
    
    public protocol Disposable {
        func dispose()
    }
    
    
    * SUBCLASSED SKNODE-RELATED CODE *
    import SpriteKit
    
    class ClickableSKSpriteNode: SKNode
    {
        let cBackground: SKSpriteNode
        let event: Event<(String, String)>
        let handler: AnyObject
    
        /*init(imageName: String, event: Event<(String, String)>)*/
        init(imageName: String, handler: (String, String) -> ())
        {
            self.cBackground = SKSpriteNode(imageNamed: imageName)
            /*self.event = event*/
            self.event = Event<(String, String)>()
            self.handler = self.event.addHander(handler)
            super.init()
        }
    
    
        override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
            let touch:UITouch = touches.first as! UITouch
            let positionInScene = touch.locationInNode(self)
    
            if self.cBackground.containsPoint(positionInScene) {
                self.event.raise("string one", "string two")
            }
        }
    
        override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
    
        }
    
        override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
    
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    
    
    * SUBCLASS OBJECT INSTANTIATION CODE *
    
    ......
    
    let startButton = ClickableSKSpriteNode(imageName: "Start.png", event: self.handleStartClick)
    
    ......
    
    func handleStartClick(string1: String, string2: String){
       DebugPring("String1 = \(string1), String2 = \(string2)")
    }
    

1 个答案:

答案 0 :(得分:0)

这是一种简单的类型不匹配。您对init的参数类型为(String, String) -> (),而不是Event<(String, String)>

我怀疑如果您需要多个订阅者,Array<T -> ()>作为您的节点子类的成员就足够了。