Reputation: 924
I am trying to filter out instances of an object in an array (remove an observer from a list of observers to be specific):
private var observers = [ChooserObserver]()
...
func unregisterObserver(observer: ChooserObserver ) {
observers = observers.filter { includeElement in includeElement === observer }
}
...
protocol ChooserObserver {
var path: String { get set }
}
Unfortunately, I get the following error:
Type 'ChooserObserver' does not conform to protocol 'AnyObject'
If I attempt to allow ChooserObserver to inherit AnyObject like so:
protocol ChooserObserver: AnyObject {
var path: String { get set }
}
I am met with the following error:
Cannot declare explicit conformance to the 'AnyObject' protocol
When I attempt to cast to AnyObject:
func unregisterObserver(observer: ChooserObserver ) {
observers = observers.filter { includeElement in includeElement as AnyObject !== observer as AnyObject }
}
I get these errors:
Partial application of struct method is not allowed
Cannot downcast from 'ChooserObserver' to non-@objc protocol type 'AnyObject'
I can only fix by appending @objc to my protocol in conjunction with the previous cast to AnyObject:
@objc protocol ChooserObserver {
var path: String { get set }
}
Is this necessary, and if so why? I realize that an NSMutableSet would probably be appropriate here, but I am trying to understand Swift's type system.
Upvotes: 1
Views: 459
Reputation: 122429
If I attempt to allow ChooserObserver to inherit AnyObject like so: I am met with the following error:
The correct syntax is
protocol ChooserObserver : class {
//...
}
(Probably Apple should have just allowed you to do : AnyObject
to avoid needing this new syntax.)
Upvotes: 3
Reputation: 27335
Protocols can be conformed by both class and value types. Identical operator only works for class instances. Identical to operator must be sure both operands are classes. I guess thats why there is such limitation. Objective-C value types cannot conform to protocols, thats why @objc protocol ChooserObserver
works.
Upvotes: 1
Reputation: 4676
Just an idea, maybe it works:
private var observerRefs = [AnyObject]()
private var observers = [ChooserObserver]()
...
func registerObserver<O where O: AnyObject, O: ChooserObserver>(observer: O) {
observerRefs.append(observer)
observers.append(observer)
}
func unregisterObserver<O where O: AnyObject, O: ChooserObserver>(observer: O) {
for let index in (observerRefs.count - 1) .. 0 {
if observerRefs[index] === observer {
observerRefs.removeAtIndex(index)
observers.removeAtIndex(index)
}
}
}
...
protocol ChooserObserver {
var path: String { get set }
}
Upvotes: 1