5

Hi I have an exception like "Cannot specialize a non-generic definition" when i'm trying to initialize List in Realm object. Does anyone know how to fix this issue? swift 3.2

class Dog: Object {
    @objc dynamic var name = ""
    @objc dynamic var age = 0 
}

class Event : Object{
    dynamic var event_id = 0
    dynamic var date : String?
    dynamic var name : String?
    dynamic var remind : Remind?
    dynamic var event_status = 0

    let dogs = List<Dog>()       "Cannot specialize a non-generic definition"

    required convenience init?(map: Map){ self.init() } 
}
  • 4
    Is it possible you haven't imported `RealmSwift` and that the `List` type exists in another part of your project? You might try: `let dogs = RealmSwift.List()` – allenh Nov 16 '17 at 18:27
  • No man, I imported : import Foundation import UIKit import Alamofire import RealmSwift import ObjectMapper import ObjectMapper_Realm import SwiftyJSON import BFKit – Roman Nikitiuk Nov 16 '17 at 23:21
  • Thanks a lot, but "RealmSwift.List()" is working instead of "List()". But in other my project "List()" is working well and i was confused. – Roman Nikitiuk Nov 16 '17 at 23:32
  • It seems like a name conflict then. You'll have to look around for other structs/classes named List. – allenh Nov 17 '17 at 00:10
  • Yeah, there is one more struct List :) – Roman Nikitiuk Nov 17 '17 at 08:06

1 Answers1

8

I wanted to give the solution to this question some context. In Swift, namespacing is implicit on a module level. If you have external modules, such as RealmSwift, which has a type List you can still have a type named List in your own module. You can even have multiple external modules with the type List.

My reasoning for the error you presented was as follows

  1. In Realm, what you posted is exactly how you're supposed to declare a list
  2. Your example compiled in the context of my project which already uses Realm Lists
  3. The error indicated suggests that the swift compiler knows that List is a valid type and in fact knows about a function named List.init(), however, the compiler is telling you that the function isn't generic.

The only answer at that point, is to assume the compiler is using a different definition of List than you are intending. The only way this happens is if the scope you're in (your project or another type), has also defined a type List, since internal types take precedence over external types. This precedence is extended further with type nesting. If you'd like to keep Realm's List as the default list, you can nest your List in another structure to provide a namespace of sorts.

The following example is as concise as possible given the complex situation.

import RealmSwift

let myGlobalDogs = List()
let myGlobalNestedListDogs = MyClass.List()
let globalDogs = RealmSwift.List<Dog>()

class List { }

class MyClass {
    class List { }

    let dogs = RealmSwift.List<Dog>()
    let myNestedListDogs = List() // type: MyModule.MyClass.List
    let myDogs = MyModule.List() // type: MyModule.List
}

class MyOtherClass {

    let dogs = RealmSwift.List<Dog>()
    let myNestedListDogs = MyClass.List() // type: MyModule.MyClass.List
    let myDogs = List() // type: MyModule.List
}

Fortunately, types/functions are usually different enough that you can't inadvertently use the wrong one without encountering an error eventually, such as the one you encountered.

allenh
  • 6,582
  • 2
  • 24
  • 40
  • This is great. I've been stuck for hours trying to figure out what to do. I couldn't return what I needed to return on my function. Thanks! +1 – CRey Dec 22 '18 at 20:44