@@ -26,7 +26,19 @@ public enum PusherChannelType {
26
26
27
27
@objcMembers
28
28
open class PusherChannel : NSObject {
29
- open var eventHandlers : [ String : [ EventHandler ] ] = [ : ]
29
+ // Access via queue for thread safety if user binds/unbinds events to a channel off the main queue
30
+ // (Concurrent reads are allowed. Writes using `.barrier` so queue waits for completion before continuing)
31
+ private let eventHandlersQueue = DispatchQueue ( label: " com.pusher.pusherswift-channel-event-handlers- \( UUID ( ) . uuidString) " ,
32
+ attributes: . concurrent)
33
+ private var eventHandlersInternal = [ String: [ EventHandler] ] ( )
34
+ open var eventHandlers : [ String : [ EventHandler ] ] {
35
+ get {
36
+ return eventHandlersQueue. sync { eventHandlersInternal }
37
+ }
38
+ set {
39
+ eventHandlersQueue. async ( flags: . barrier) { self . eventHandlersInternal = newValue }
40
+ }
41
+ }
30
42
open var subscribed = false
31
43
public let name : String
32
44
open weak var connection : PusherConnection ?
@@ -35,15 +47,15 @@ open class PusherChannel: NSObject {
35
47
public var auth : PusherAuth ?
36
48
37
49
// Wrap accesses to the decryption key in a serial queue because it will be accessed from multiple threads
38
- @nonobjc private var decryptionKeyQueue = DispatchQueue ( label: " com.pusher.pusherswift-channel-decryption-key- \( UUID ( ) . uuidString) " )
50
+ @nonobjc private var decryptionKeyQueue = DispatchQueue ( label: " com.pusher.pusherswift-channel-decryption-key- \( UUID ( ) . uuidString) " ,
51
+ attributes: . concurrent)
39
52
@nonobjc private var decryptionKeyInternal : String ?
40
53
@nonobjc internal var decryptionKey : String ? {
41
54
get {
42
55
return decryptionKeyQueue. sync { decryptionKeyInternal }
43
56
}
44
-
45
57
set {
46
- decryptionKeyQueue. sync { decryptionKeyInternal = newValue }
58
+ decryptionKeyQueue. async ( flags : . barrier ) { self . decryptionKeyInternal = newValue }
47
59
}
48
60
}
49
61
0 commit comments