草庐IT

关于 ios:Generic 子类化的类

codeneng 2023-03-28 原文

Generic on class that is subclassed

在我用 Swift 编写的应用程序中,我有以下类结构。 A 类有一个静态方法,它可以做一些事情,但在一个非常简单的形式中,它看起来像下面的代码。

1
2
3
4
5
6
class A {
    class func create<T: A>() -> T? {
        println(NSStringFromClass(T));
        return nil;
    }
}

B 是类 A 的子类。

1
2
class B : A {
}

现在,当我执行以下代码时,println 命令输出 A 而不是 B

1
var myVar:B? = B.create();

我不确定我在这里做错了什么,但我希望它输出 B.

create方法中调试和放置断点时,$swift.type.T的值被定义为Builtin.RawPointer MyApp.A而不是B

  • 我无法重现,我得到 "MyApp.B" 作为输出。


您在 A 上的通用类方法对我来说没有意义。相反,我实际上会使用类似下面的代码。这样它会创建一个 Self 的实例,它是你调用它的任何类。在这种情况下不需要泛型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class A {
    required init() {}
    class func create() -> Self {
        return self()
    }
    func test() -> String {
        return"A"
    }
}
class B : A {
    override func test() -> String {
        return"B"
    }
}

let b = B.create() //"{A}" according to the playground, but it is a"B" instance!
b.test() //"B"

请注意,A 需要一个必需的初始化程序,因为使用了 Self。在 Playground 中执行此操作时,创建的实例在右侧显示为 {A}。我相信这是 Xcode 中的错误,实际类型是正确的。

编辑:

我相信上面的代码不是您想要的,现在我确实得到了您想要做的。我建议不要根据实际的类名来这样做,而是使用泛型类为您创建实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
protocol Entity {
    init()
    class func entityName() -> String
}
class EntityFactory<T : Entity> {
    class func newEntity() -> T? {
        var entity: T?
        // ... create entity here using T.entityName()
        return entity
    }
}
class Person : Entity {
    required init() {}
    class func entityName() -> String {
        return"Person"
    }
}

let person = EntityFactory<Person>.newEntity()

认为这是一个更优雅的解决方案,它将创建实体的责任转移到一个单独的泛型类中。这会产生可维护和可测试的代码。您甚至可以将其进一步抽象出来用于单元测试目的,但这似乎有点超出范围。

  • 静态方法实际上比仅返回类本身的干净实例要复杂一些。它涉及查询 CoreData 以获取具有指定类型的记录,如果不存在,则创建一个 CoreData 对象并返回它。
  • @WimHaanstra:如果您的问题是关于创建 Core Data 托管对象,那么这个 stackoverflow.com/questions/24537238/... 或这个 stackoverflow.com/questions/24834753/... 可能会很有趣。
  • 谢谢,我终于选择了 EntityFactory 方法。这以一种非常干净的方式解决了它。我没有包含 entityName 方法,因为我使用 NSStringFromClass() 方法。

有关关于 ios:Generic 子类化的类的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  3. Ruby——嵌套类和子类是一回事吗? - 2

    下面例子中的Nested和Child有什么区别?是否只是同一事物的不同语法?classParentclassNested...endendclassChild 最佳答案 不,它们是不同的。嵌套:Computer之外的“Processor”类只能作为Computer::Processor访问。嵌套为内部类(namespace)提供上下文。对于ruby​​解释器Computer和Computer::Processor只是两个独立的类。classComputerclassProcessor#Tocreateanobjectforthisc

  4. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  5. ruby - 更改 ActiveRecord 中对象的类 - 2

    假设我有一个FireNinja我的数据库中的对象,使用单表继承存储。后来才知道他真的是WaterNinja.将他更改为不同的子类的最干净的方法是什么?更好的是,我很想创建一个新的WaterNinja对象并替换旧的FireNinja在数据库中,保留ID。编辑我知道如何创建新的WaterNinja来self现有FireNinja的对象,我也知道我可以删除旧的并保存新的。我想做的是改变现有项目的类别。我是通过创建一个新对象并执行一些ActiveRecord魔法来替换行,还是通过对对象本身做一些疯狂的事情,或者甚至通过删除它并使用相同的ID重新插入来做到这一点,这是问题的一部分。

  6. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  7. Ruby - 如何处理子类意外覆盖父类(super class)私有(private)字段的问题? - 2

    假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案

  8. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  9. 带有 attr_accessor 的类上的 Ruby instance_eval - 2

    我了解instance_eval和class_eval之间的基本区别。我在玩弄时发现的是一些涉及attr_accessor的奇怪东西。这是一个例子:A=Class.newA.class_eval{attr_accessor:x}a=A.newa.x="x"a.x=>"x"#...expectedA.instance_eval{attr_accessor:y}A.y="y"=>NoMethodError:undefinedmethod`y='forA:Classa.y="y"=>"y"#WHATTT?这是怎么回事:instance_eval没有访问我们的A类(对象)然后它实际上将它添加到

  10. ruby-on-rails - 关于 Ruby 的一般问题 - 2

    我在我的rails应用程序中安装了来自github.com的acts_as_versioned插件,但有一段代码我不完全理解,我希望有人能帮我解决这个问题class_eval我知道block内的方法(或任何它是什么)被定义为类内的实例方法,但我在插件的任何地方都找不到定义为常量的CLASS_METHODS,而且我也不确定是什么here,并且有问题的代码从lib/acts_as_versioned.rb的第199行开始。如果有人愿意告诉我这里的内幕,我将不胜感激。谢谢-C 最佳答案 这是一个异端。http://en.wikipedia

随机推荐