0

Consider I have one model and a base model for it:

class BaseModel: NSObject {
    var name = ""
}

class Model: BaseModel {
    var desc = "abc"
}

I added a services to work with those models:

class AbstractService<T: NSObject>: NSObject {
    var items = [T]()
}

class BaseModelService<T: BaseModel>: AbstractService<BaseModel> {
}

class ModelService<T: Model>: BaseModelService<Model> {
}

Now I want to access items variable from ModelService and expect to get an array of Models, but I get BaseModels instead:

Error message: Cannot assign a value of type [BaseModel] to a value of type [Model]

Did I miss something with generics?

Here is a full code for Playground:

//: Playground - noun: a place where people can play

import UIKit

/// Models:
class BaseModel: NSObject {
    var name = ""
}

class Model: BaseModel {
    var desc = "abc"
}

/// Services:
class AbstractService<T: NSObject>: NSObject {
    var items = [T]()
}

class BaseModelService<T: BaseModel>: AbstractService<BaseModel> {
}

class ModelService<T: Model>: BaseModelService<Model> {
}

/// ViewController:
class ViewController: UIViewController {

    let modelService = ModelService()
    var items = [Model]()

    override func viewDidLoad() {
        super.viewDidLoad()

        items = modelService.items // The error appears here: Cannot assign a value of type [BaseModel] to a value of type [Model]
    }

}

2 Answers 2

2

The problem is that you force BaseModelService to be a subclass of AbstractModelService<BaseModel> which means that items is typed [BaseModel]. Declare BaseModelService as follows:

class BaseModelService<T: BaseModel>: AbstractService<T> {

Then you are good to go.

Sign up to request clarification or add additional context in comments.

Comments

1

In your case, the declarations should be:

class BaseModelService<T: BaseModel>: AbstractService<T> {
}

class ModelService: BaseModelService<Model> {
}

When you do:

class BaseModelService<T: BaseModel>: AbstractService<BaseModel> {
}

T for AbstractService and T for BaseModelService are two distinct types. The former constrained to concrete BaseModel, whereas the latter is constrained to subtype of BaseModel, and not used at all.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.