首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >斯威夫特,来自AnyObject

斯威夫特,来自AnyObject
EN

Stack Overflow用户
提问于 2014-09-18 23:25:57
回答 2查看 1.7K关注 0票数 3

是否有可能从AnyObject中获得Self?

举个例子:

代码语言:javascript
复制
// Superclass
class ManagedObject {
  class func findByID(id: String) -> AnyObject? {
    let objects = objectsWithPredicate(NSPredicate(format: "id == %@", id))
    return objects.firstObject() // Returns AnyObject
  }
}

// Subclass
class User : ManagedObject {
  class func returnFirstSelf() -> Self? {
    return findById("1") // This doesn't work because it returns AnyObject, but I need Self.
  }
}

如果不是,那么确保在调用User.returnFirstSelf()时编译器返回User,调用UserSubclass.returnFirstSelf()时返回UserSubclass的最佳替代方法是什么。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-18 23:49:04

您可以简单地从类函数返回User?,如果这是一个选项:

代码语言:javascript
复制
public class func returnFirstSelf() -> User? {
    if let found = findByID("1") as? User {
        return found
    }
    return nil
}

目前没有办法(我知道)返回Self?与Swift的现状。问题是Self有点.“动态”含义,与具体类型、协议甚至泛型分开。演示这一点的一个特殊示例是:如果您有一个扩展StudentUser的类User,该怎么办?如果您试图像这样实现它:

代码语言:javascript
复制
class func returnFirstSelf() -> Self? {
    if let found = findById("1") as? Self { // Note the check that 'found' is a 'Self'
        return found
    }
    return nil
}

然后会遇到编译器错误,因为不能在协议或类方法的结果之外使用Self。如果你试图像这样实现它:

代码语言:javascript
复制
class func returnFirstSelf() -> Self? {
    if let found = findById("1") as? User { // Note 'User' instead of 'Self'
        return found
    }
    return nil
}

然后您就会冒Self实际上是StudentUser的风险,即使您通过了要求foundUser的检查,也不能保证found将是StudentUser。在StudentUser不覆盖该方法以确保as?检查StudentUser的情况下,就会发生这种情况。

这里的关键缺陷--在我看来--是,您不能在类方法上使用required关键字,需要子类来覆盖它们。这将使编译器能够确保任何子类都重写了该方法,并提供了一个可以保证类型安全的实现。

票数 4
EN

Stack Overflow用户

发布于 2015-09-27 14:26:51

克雷格·奥蒂斯的回答是对的。但是,一个选项是创建一个副本构造函数。这可能不适用于请求者从NSManagedObject继承的场景,但它应该适用于非托管对象。

代码语言:javascript
复制
required init(user: User) {
    super.init(user: User) // or super.init() if top of inheritance.
    self.name = user.name
    self.email = user.email
    // etc.
}

class func returnFirstSelf() -> Self? {
    if let found = findById("1") { // Note the check that 'found' is a 'Self'
        return self.init(copy: found as! User)
    }
    return nil
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25924025

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档