내가 만든 클래스 인스턴스의 속성이 겉으로보기에 값을 잃어 버리는 문제가 있습니다. 기본적으로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()
}
}