2015-01-09 2 views
3

내가 만든 클래스 인스턴스의 속성이 겉으로보기에 값을 잃어 버리는 문제가 있습니다. 기본적으로Swift에서 인스턴스의 속성에 대한 참조가 손실되었습니다.

이 같은 클래스가하십시오의 ViewController 내부

class Channel {  
    var callbacks: [String: (JSON) -> Void] 
    var subscribed = false 
    let name: String 

    init(name: String) { 
     self.name = name 
     self.callbacks = [:] 
    } 

    func bind(eventName: String, callback: (JSON) -> Void) { 
     self.callbacks[eventName] = callback 
    } 

    func handleEvent(eventName: String, eventData: String) { 
     if let cb = self.callbacks[eventName] { 
      let json = JSON(object: eventData) 
      cb(json) 
     } 
    } 
} 

다음을 나는 다음과 같은 코드가 있습니다 그것은 키 -이 있음을 보여줍니다

class ViewController: UIViewController { 
    let wSock = wSocket(key: "afa4d38348f89ba9c398") 

    func channelSetup() { 
     var ch = wSock.subscribe("test-channel") 
     ch.bind("test-event", { (data: JSON) -> Void in 
      println("I'm the callback getting called") 
     }) 
     println(ch.callbacks) 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad()   

     channelSetup()   
    } 
} 

ch.callbacks의 println 메소드에서을 값 쌍.

그러나 채널이 소켓을 통해 수신 된 메시지가있을 때 나중에 이벤트를 수신하면 콜백은 더 이상 존재하지 않습니다. 코드의 관점에서, 여기에 전체의 코드는 다음 웹 소켓은 주어진 채널에 대한 일부 데이터를 수신 할 때 그래서 기본적으로

import UIKit 

class ViewController: UIViewController { 
    let wSock = wSocketClient(key: "afa4d38348f89ba9c398") 

    func channelSetup() { 
     var ch = wSock.subscribe("test-channel") 
     ch.bind("test-event", { (data: JSON) -> Void in 
      println("I'm the callback getting called") 
     }) 
     println(ch.callbacks) 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad()   

     channelSetup()   
    } 
} 

class wSocketClient { 
    let connection: Connection 

    init(key: String, encrypted: Bool = false) { 
     var url = "SOCKET_URL" 
     connection = Connection(url: url) 
    } 

    func subscribe(channelName: String) -> Channel { 
     return self.connection.addChannel(channelName) 
    } 

    func connect() { 
     self.connection.open() 
    } 
} 

class Connection: WebSocketDelegate { 
    let url: String 
    lazy var socket: WebSocket = { [unowned self] in 
     return self.connectInternal() 
    }() 
    let connected = false 
    var channels = Channels() 

    init(url: String) { 
     self.url = url 
    } 

    func addChannel(channelName: String) -> Channel { 
     return Channel(name: channelName) 
    } 

    func open() { 
     if self.connected { 
      return 
     } else { 
      self.socket = connectInternal() 
     } 
    } 

    func connectInternal() -> WebSocket { 
     let ws = WebSocket(url: NSURL(string: self.url)!) 
     ws.delegate = self 
     ws.connect() 
     return ws 
    } 

    func websocketDidReceiveMessage(text: String) { 
     let data = (text as NSString).dataUsingEncoding(NSUTF8StringEncoding) 
     let json = JSON(data: data!) 

     if let channelName = json["channel"].stringValue { 
      if let internalChannel = self.channels.find(channelName) { 
       if let eName = json["event"].stringValue { 
        if let eData = json["data"].stringValue { 
         internalChannel.handleEvent(eName, eventData: eData) // this is the part of the code where the channel should eventually call the callback 
        } 
       } 
      } 
     } 
    } 
} 

class Channel {  
    var callbacks: [String: (JSON) -> Void] 
    var subscribed = false 
    let name: String 

    init(name: String) { 
     self.name = name 
     self.callbacks = [:] 
    } 

    func bind(eventName: String, callback: (JSON) -> Void) { 
     self.callbacks[eventName] = callback 
    } 

    func handleEvent(eventName: String, eventData: String) { 
     if let cb = self.callbacks[eventName] { // here self.callbacks is empty and the callback has disappeared 
      let json = JSON(object: eventData) 
      cb(json) 
     } 
    } 
} 

class Channels { 
    var channels = [String: Channel]() 

    func add(channelName: String) -> Channel { 
     if let channel = self.channels[channelName] { 
      return channel 
     } else { 
      let newChannel = Channel(name: channelName) 
      self.channels[channelName] = newChannel 
      return newChannel 
     } 
    } 

    func find(channelName: String) -> Channel? { 
     return self.channels[channelName] 
    } 
} 

는,이 이벤트 이름을 확인하고, 그와 콜백이 있다면해야 이벤트 이름, 해당 이벤트 이름과 관련된 콜백을 호출하십시오. 그러나 handleEvent 메서드가 호출 될 때 channel은 채널의 callbacks 속성에 callback이있는 것으로 표시된 viewDidLoad의 하단에 있더라도 분명히 콜백이 없습니다.

콜백이 사라지는 위치와 이유에 대한 의견이 있으십니까?

업데이트

지금 채널의 정의가이처럼 있도록 channelSetup 기능의 ch 외부를 이동하려고했습니다,하지만 운 :

class ViewController: UIViewController { 
    let wSock = wSocket(key: "afa4d38348f89ba9c398") 
    var ch: Channel = nil 

    func channelSetup() { 
     ch = wSock.subscribe("test-channel") 
     ch.bind("test-event", { (data: JSON) -> Void in 
      println("I'm the callback getting called") 
     }) 
     println(ch.callbacks) 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     channelSetup() 
    } 
} 

답변

1

내가 해결했습니다 그러나 이것이 내가 이해하지 못했던 스위프트에서 진행되고있는 것이기 때문에가 아닙니다. 대신 코드를 설정 한 방법으로 중복 된 채널 객체가 만들어지고 콜백 중 하나만 채널에 추가된다는 의미였습니다.

관련 문제