gpt4 book ai didi

swift - 关于如何拥有通用类、实现协议(protocol)、转换为该协议(protocol)并允许检索属性的任何想法?

转载 作者:可可西里 更新时间:2023-11-01 01:06:23 25 4
gpt4 key购买 nike

我有一个简单的 Result 对象,它应该包含一个对象(类、结构或枚举)和一个 Bool 来说明它是否被取消。我需要沿着它的路径询问这个对象(在它到达目的地之前,目的地知道期望什么样的对象)以确定它是否被取消(而不用担心那个时候伴随的对象)。我的对象看起来像:

import Foundation

@objc protocol Resultable {
var didCancel: Bool { get }
}

class Result<T>: Resultable {
let didCancel: Bool
let object: T?

init(didCancel: Bool, object: T?) {
self.didCancel = didCancel
self.object = object
}
}

我的想法是我的 Result 对象可以包装 didCancel 标志和实际对象(可以是任何类型),事实上它实现了 Resultable 协议(protocol)意味着我可以随时询问它是否通过将其转换为 Resultable 来取消它。

我理解(虽然不喜欢)协议(protocol)必须以 @objc 为前缀,以便我们可以转换为它(根据 Apple 文档)。不幸的是,当我运行下面的代码时(在 playground 或项目中),我得到了一个讨厌的 "does not implement methodSignatureForSelector:" 错误消息:

let test = Result(didCancel: false, object: NSArray())

println(test.didCancel)
// transform the object into the form it will be received in
let anyTest: AnyObject = test

if let castTest = anyTest as? Resultable {
println(castTest.didCancel)
}

似乎尽管协议(protocol)以@objc为前缀,它也希望实际的类继承自NSObject(这不是Apple明确的要求).这显然是泛型类的问题。

我在这里遗漏了什么吗?有什么方法可以让它工作吗?如果做不到这一点,是否有任何解决方法(尽管我坚信这种事情应该是可能的 - 也许我们可以希望 Apple 在某个阶段取消 @objc 协议(protocol)转换要求)?

更新看起来这是用 Swift 1.2 解决的您现在可以转换为非 ObjC 协议(protocol),而无需从 NSObject 继承对象。

最佳答案

It seems that despite the protocol being prefixed with @objc, it also wants the actual class to inherit from NSObject

这不是真的。例如,以下代码按预期工作:

@objc protocol MyProtocol {
var flag: Bool { get }
}

class MyClass: MyProtocol {
let flag = true
}

let foo:AnyObject = MyClass()
if let p = foo as? MyProtocol {
println(p.flag)
}

问题在于:在 Swift 泛型类中声明的任何方法/属性在 Objective-C 中都是不可见的。因此,从@objc protocol Resultable的角度来看, didCancelResult<T> 中声明的属性(property)是看不见的。这就是为什么 methodSignatureForSelector:被称为。

这里的解决方法非常烦人:您必须为 Result 设置非通用 基类实现 didCancel .

@objc protocol Resultable {
var didCancel: Bool { get }
}

class ResultBase: Resultable {
let didCancel: Bool
init(didCancel: Bool) { self.didCancel = didCancel }
}

class Result<T>: ResultBase, Resultable {
// ^^^^^^^^^^^^
// You have to explicitly conforms `Resultable` here as well for some reason :/

let object: T?

init(didCancel: Bool, object: T?) {
self.object = object
super.init(didCancel: didCancel)
}
}

let test = Result(didCancel: false, object: NSArray())
let anyTest: AnyObject = test
if let castTest = anyTest as? Resultable {
println(castTest.didCancel) // -> outputs "false"
}

关于swift - 关于如何拥有通用类、实现协议(protocol)、转换为该协议(protocol)并允许检索属性的任何想法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28296176/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com