Reputation: 118
I use Xcode 7 beta 6 and I have code like this:
public protocol ViewForViewModel {
typealias ViewModelType
var viewModel: ViewModelType! { get set }
func bindToViewModel()
}
func afterViewInstantiated <V : ViewForViewModel where V: UIViewController, V.ViewModelType: AnyObject>(view : V, viewModel: V.ViewModelType) -> V {
//Cannot assign to property: 'view' is a 'let' constant
view.viewModel = viewModel // error here
VMTracker.append(viewModel, view: view)
return view
}
Compiler complains on assignment view.viewModel = viewModel
.
I'm understand what ViewForViewModel
protocol is not constrained to class by itself, but V
type is constrained to UIViewController
class. Is it a bug or a feature?
UPD: it even complains about UITableViewCell
variable:
func registerBinding<V: BindableCellView where V: UITableViewCell>(viewType: V.Type) {
let typeName = nameOfType(V.ViewModelType.self)
bindings[typeName] = { [unowned self] viewModel, indexPath in
let view = self.tableView.dequeueReusableCellWithIdentifier(V.CellIdentifier, forIndexPath: indexPath) as! V
//Cannot assign to 'viewModel' because 'view' is a 'let' constant
//However view is UITableViewCell that support ViewForViewModel protocol
view.viewModel = viewModel as! V.ViewModelType
self.onWillBind?(view, indexPath)
view.bindToViewModel()
self.onDidBind?(view, indexPath)
return view
}
}
Upvotes: 0
Views: 1355
Reputation: 356
If the Compiler can't infer, that the parameter will always be a reference type, you can always add class
to the protocol declaration:
public protocol ViewForViewModel: class {
typealias ViewModelType
var viewModel: ViewModelType! { get set }
func bindToViewModel()
}
Once the protocol is marked up like that, you should be able to assign values to the property even if the object is stored in a constant.
Upvotes: 6
Reputation: 13243
In the first case it should be considered an "unimplemented feature" (that the compiler cannot infer the behavior of a class in this context). So to fix it you have to make the value
a var
:
func afterViewInstantiated <V : ViewForViewModel where V: UIViewController, V.ViewModelType: AnyObject>(var view : V, viewModel: V.ViewModelType) -> V
In the second case you should provide more information about the error (message) and the types. Where does V
come from?
Upvotes: 1
Reputation: 13893
If the compiler is complaining about the protocol not being able to be used as a non-generic type, delete the typealias
in the protocol.
BTW, what is the use case for this?
Upvotes: 0