Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 如何在Swift中返回instancetype_Objective C_Swift - Fatal编程技术网

Objective c 如何在Swift中返回instancetype

Objective c 如何在Swift中返回instancetype,objective-c,swift,Objective C,Swift,我想对某个类进行扩展以返回运行时类型对象 例如,我创建了类A的扩展 extension A { class func niceObject() -> XXXXX { // in objective-c is instancetype return .... } } 所以,任何人都知道Swift中有instancetype关键字或不替换xxxxx,我可以在A的子类上调用此函数,而无需手动强制转换 var b: B = B.niceObject() 谢谢至少

我想对某个类进行扩展以返回运行时类型对象

例如,我创建了类A的扩展

extension A {
    class func niceObject() -> XXXXX { // in objective-c is instancetype
        return ....
    }
}
所以,任何人都知道Swift中有instancetype关键字或不替换
xxxxx
,我可以在A的子类上调用此函数,而无需手动强制转换

var b: B = B.niceObject()

谢谢

至少在procotols中,您可以使用
Self
。这表示
self
的实际类型。不过,我不确定是否需要扩展

例如,请参见
equalable
的定义:

protocol Equatable {
    func ==(lhs: Self, rhs: Self) -> Bool
}

有一个关键字
Self
,它可以放在两个地方-在协议中(见Jean-Philippe Pellet的回答)和作为
方法的结果:

extension A {
    class func niceObject() -> Self? {
        return nil
    }
}
不幸的是,这对您没有帮助,因为以下内容无效

extension A {
     class func niceObject() -> Self? {
         //A can't be converted to Self
         return A()
     }
 }
该错误是由以下事实引起的:当您从
A继承时

class B : A {
}
然后

将实际返回一个
A
实例,该实例不能转换为
Self
Self
B

@Grimxn找到了正确的解决方案():

您必须向基类添加所需的初始值设定项,例如

class A {
   @required init() {
   } 
}
然后您可以使用
self()


你能做到。操场代码如下。niceObject()必须返回的是self()。此外,基类上必须有
required
init

class A {
    required init() {
    }

    func whatClassAmI() -> String {
        return "Class A"
    }
}

class B: A {
    required init() {
        super.init()
    } 
    override func whatClassAmI() -> String {
        return "Class B"
    }
}

let a = A()
let sa = a.whatClassAmI() // "Class A", of course

let b = B()
let sb = b.whatClassAmI() // "Class B", of course

extension A {
    class func niceObject() -> Self {
        return self.init()
    }
}

let aa = A.niceObject()
let saa = aa.whatClassAmI() // "Class A"

let bb = B.niceObject()
let sbb = bb.whatClassAmI() // "Class B", as required

当您使用Objective-C中的Swift API时,编译器通常会执行直接翻译。例如,Swift API
func播放歌曲(名称:String)
作为
-(void)播放歌曲:(NSString*)名称导入Objective-C中

但是,有一个例外:当您在Objective-C中使用时,编译器将文本“
initWith
”添加到方法的开头,并正确地将原始初始值设定项中的第一个字符大写


例如,此Swift初始值设定项
init(songName:String,artist:String)
在Objective-C中作为
-(instancetype)initWithSongName:(NSString*)songName艺术家:(NSString*)artist
导入。

从Swift编程语言资源中查看此页面,尤其是“向下播放”:我认为您提到的错误不是因为运行
B.niceObject()
。这是编译错误。似乎我们不能在扩展中使用Self,除非我们可以返回对象类型Self@ZoonNooz我试图解释为什么不能在Swift中返回
Self
。虽然如果我们能以那种方式访问
Self
会有帮助。我现在明白你的意思了。顺便说一句,在objc中,我在CoreDatabase中根据当前类型查询NSManagedObject。所以我可以将它作为NSManagedObject返回,当我调用函数时,它将是子类类型。但不是在swift中。就我个人而言,我必须对扩展名A{class func niceObject()->[Self]{//doStuff返回MyArrayOfSelf}}

做同样的操作,它不起作用,不幸的是,dynamicType不支持这一点,因此,如果您只有基类引用,那么它就可以工作。请注意,如果您正在为
字典
执行
扩展
,并且希望返回相同类型的
字典
,则必须执行
扩展字典{func changeSomeThing()->字典{return self}}
extension A {
     class func niceObject() -> Self {
         return self()
     }
 }
class A {
    required init() {
    }

    func whatClassAmI() -> String {
        return "Class A"
    }
}

class B: A {
    required init() {
        super.init()
    } 
    override func whatClassAmI() -> String {
        return "Class B"
    }
}

let a = A()
let sa = a.whatClassAmI() // "Class A", of course

let b = B()
let sb = b.whatClassAmI() // "Class B", of course

extension A {
    class func niceObject() -> Self {
        return self.init()
    }
}

let aa = A.niceObject()
let saa = aa.whatClassAmI() // "Class A"

let bb = B.niceObject()
let sbb = bb.whatClassAmI() // "Class B", as required