0

I try to init a class in a generic way with parameters but it doesn't work...

protocol EntityCreator: class {
    func createEntity<EntityType: EntityClass & EntityCreatorInitializable>(type: EntityType.Type, _ initialize: @escaping (EntityType) -> Void)
}

protocol EntityCreatorInitializable {
    init(entityCreator: EntityCreator)
}

class EntityClass: NSObject { }

class MyClass: EntityClass, EntityCreatorInitializable {
    required init(entityCreator: EntityCreator) {
        super.init()
        // use the entityCreator
    }
}

// On the entity creator implementation :

class EntityCreatorImplementation: EntityCreator {
    var toAdd = Set<EntityClass>()

    func createEntity<EntityType: EntityClass & EntityCreatorInitializable>(type: EntityType.Type, _ initialize: @escaping (EntityType) -> Void) {
        // This creation doesn't work...
        let newEntity = EntityType(entityCreator: self)
        initialize(newEntity)
        self.toAdd.insert(newEntity)
    }
}

The error I have at compilation is

Non-nominal type 'EntityType' does not support explicit initialization

Any Ideas on how to achieve this ?

Thanks !!

EDIT : I added the definition of EntityClass. In my project it is a GKEntity, but the problem is the same with just NSObject

EDIT : added the toAdd Set, forgot to declare it (but used it in the createEntity method)

zarghol
  • 478
  • 5
  • 19

2 Answers2

1

Change

EntityType: EntityClass & EntityCreatorInitializable

to

EntityType: EntityCreatorInitializable
matt
  • 515,959
  • 87
  • 875
  • 1,141
  • but this way, the line ```self.toAdd.insert(newEntity)``` doesn't work, as toAdd is a Set of ```EntityClass```.... I can use ```as! EntityClass``` but it is too ugly... – zarghol May 20 '18 at 21:46
  • But you didn't show a definition of `toAdd.insert` in the code you posted. So I had to comment that out. You must post _minimal complete verifiable_ example code. And as you rightly say, if you somehow _know_ that this is also an EntityClass, then you _can_ cast it. Your structure is very odd and its purpose eludes me; all I'm doing is getting you past the compile error you are complaining about, and I think I did that successfully. – matt May 20 '18 at 21:49
0

if you want to be able to initialize a lot of different types, you should define a new protocol, check this answer

protocol EntityCreator: class {
        func createEntity<EntityType: EntityClass & EntityCreatorInitializable>(type: EntityType.Type, _ initialize: @escaping (EntityType) -> Void)
    }

    protocol EntityCreatorInitializable {
        init(entityCreator: EntityCreator)
    }

    class EntityClass: NSObject { }

    class MyClass: EntityClass, EntityCreatorInitializable {
        public required init(entityCreator: EntityCreator) {
            super.init()
            // use the entityCreator
        }
    }

    // On the entity creator implementation :

    class EntityCreatorImplementation: EntityCreator {
        func createEntity<EntityType: EntityCreatorInitializable>(type: EntityType.Type, _ initialize: @escaping (EntityType) -> Void) {

            // This creation doesn't work...
            let newEntity = EntityType.init(entityCreator:self)
           // initialize(newEntity)
           // self.toAdd.insert(newEntity)
        }
a.masri
  • 2,439
  • 1
  • 14
  • 32