Swift compile error when subclassing NSObject and using generics

瘦欲@ 提交于 2019-12-04 01:31:20

I found a workaround to this problem

class Wrapper<T> {
    let _val: T[]

    init(_ v: T) {
        _val = [v]
    }

    var val : T {
        get {
            return _val[0]
        }
        set {
            _val[0] = newValue
        }
    }
}

Since Array is a reference type (even though it is struct), the size of Wrapper class is now fixed and compiler can handle it.

I think its an X-code bug with generics and NSObject

class Foo<T>:NSObject{
    let _foo:T?

    init(foo:T){
        _foo  = foo
    }
}

gives swiftc failed with exit code 254

Removing the NSObject Works OK. ie:

class Foo<T>{
    let _foo:T?

    init(foo:T){
        _foo  = foo
    }
}

Or adding a constraint to the generic seems to work. ie:

class Foo<T:AnyObject>:NSObject{
    let _foo:T?

    init(foo:T){
        _foo  = foo
    }
}

I fiddled with your interesting (+1) snippet of code, and here's the closest code I could get while avoiding the compiler error:

struct Wrapper<T>  {
    var obj : T

    init(_ x : T) {
        obj = x
    }
}

So, if you don't really need Wrapper to be a class, then you'll be able to move on... until next release of Xcode ;)

As I see it, generics do not like NSObjects types, only AnyObject ones..

NSObject does not conform to AnyObject (they are different by nature and functionality) .. meaning you cannot use Array instead of NSArray if you need to create a generic method. I think this is the reason they left NSArray in swift .. because they still have NS.. things left behind .. The most important one is CoreData. I was trying to make a generic NSManagedObject class to derive from, that would use this powerful feature (generics).. I couldn't do it.

This little code snippet (another +1 from me) still causes a compiler crash in Xcode 7 beta 1, I guess it is intended that the code is not a valid class definition. A polite error message instead of a crash would be appreciated if anyone at Cupertino listens in to this thread.

I resolved it by constraining the generic parameter to implement NSObjectProtocol

class Wrapper<T:NSObjectProtocol> : NSObject
{
   let obj : T
   init(x : T) { self.obj = x }
}

This was useful for me when constructing a function that matches Wrapper<T> whenever T is a subclass of NSManagedObject.

For Swift 2.0. This issue is no longer valid.

You can have a class like this and the compiler will not complain.

class Wrapper<T> : NSObject {
    let obj : T

    init(x : T) {
        self.obj = x
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!