I am converting an app from Objective-C to Swift 2.0 and while converting an NSView
-subclass, I am getting an error while trying to store a weak
back-reference from a CALayer
to the ActionViewItemInternal
which is needed so that the layer drawing code can access the item data. I want to use a weak
reference in order to avoid a retain-cycle (item object retains layer so layer needs a weak reference back to the item object).
class WeakReference {
weak var reference: AnyObject?
init(reference: AnyObject) {
self.reference = reference
}
}
class ActionView: NSView {
// Used to store an item in ActionView.items
private class ActionViewItemInternal {
var actionViewItem: ActionViewItem
var layer: CALayer
...
init(withItem actionViewItem: ActionViewItem) {
self.actionViewItem = actionViewItem
let layer = CALayer()
// !!!!!!!!!!!!!!!!!!!!!!!!!!
// other init and error here:
// !!!!!!!!!!!!!!!!!!!!!!!!!!
layer.setValue(value: WeakReference(reference: self), forKey: "ActionViewItem")
self.layer = layer
}
}
var items: [ActionViewItem] = [ActionViewItem]()
...
}
Where ActionItemView
is defined as:
@objc protocol ActionViewItem {
var name: String { get set }
var icon: NSImage { get set }
var enabled: Bool { get set }
}
I am getting the error:
ActionView.swift:73:19: Cannot invoke 'setValue' with an argument list of type '(value: WeakReference, forKey: String)'
Xcode version: Xcode 7.0 beta 1. Deployment targets tried: 10.9, 10.10 and 10.11.
EDIT: I have tried using NSValue
, as per @rickster's suggestion, but the error remains:
layer.setValue(value: NSValue(nonretainedObject: self), forKey: "ActionViewItem")
ActionView.swift:72:19: Cannot invoke 'setValue' with an argument list of type '(value: NSValue, forKey: String)'
The
setValue(_:forKey:)
method requires an ObjC object for the value — you're passing an instance of a pure Swift class. If you make yourWeakReference
class either annotated with@objc
or inherit fromNSObject
that call should succeed.However, you don't need your own class for this purpose anyway... The
NSValue
methodvalueWithNonretainedObject
does the same thing.Oh, and on closer inspection: you're using an extra argument label in your call. It should be like
setValue(myvalue, forKey: mykey)
.