标签: swift-protocols

为什么我们不能转换为具有关联类型的协议类型,而是使用泛型达到相同的效果?

考虑这段代码:

extension Collection {
    func foo() -> Int {
        if self.first is Collection {
            return (self.first as! Collection).underestimatedCount // ERROR
        }
        else {
            return self.underestimatedCount
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我们得到了令人恐惧且明显令人困惑的情况:

协议“Collection”只能用作通用约束,因为它具有 Self 或关联的类型要求。

然而,这很高兴编译:

func foo<C: Collection>(_ c: C) -> Int where C.Iterator.Element: Collection {
    if let first = c.first {
        return first.underestimatedCount // *
    } else {
        return c.underestimatedCount
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么?!

特别是,编译器不知道关联*类型(的类型)first是如何实现的;它只得到了它们已经得到的承诺(因为任何类型的对象都Collection 必须实现它们)。第一个示例中也有同样的保证!那么为什么编译器会抱怨其中之一而不是另一个呢?

我的问题是:在 line 处*,编译器知道什么是它不 in …

casting typechecking associated-types swift swift-protocols

2
推荐指数
1
解决办法
1571
查看次数

为什么我的控制器不符合 NSObjectProtocol?

我正在使用 Xcode 和 swift 3 为我开发一个项目。我想做的是如下。

class SCViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate{
    //code here
}
Run Code Online (Sandbox Code Playgroud)

但这给了我一个错误SCViewController不符合协议NSObjectProtocol

我想同时遵守 UIViewController 和 AVCaptureMetadataOutputObjectsDelegate。请帮助我解决这个问题。

xcode ios swift swift-protocols

2
推荐指数
1
解决办法
3815
查看次数

协议内部的 Swift 协议

我遇到了 Swift 协议的问题。我有这样的事情:

\n\n
protocol OnboardingPage {\n  var viewModel: OnboardingPageViewModel! { get }\n}\n\nprotocol OnboardingPageViewModel {\n  func getValue() -> Bool\n}\n\n// ---\n\nclass FirstNameViewController: UIViewController, OnboardingPage {\n  var viewModel: FirstNameViewModel!\n}\n\nclass FirstNameViewModel: OnboardingPageViewModel {\n  func getValue() -> Bool {\n    return true\n  }\n}\n\nclass GenderViewController: UIViewController, OnboardingPage {\n  var viewModel: GenderViewModel!\n}\n\nclass GenderViewModel: OnboardingPageViewModel {\n  func getValue() -> Bool {\n    return false\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我有一堆确认协议的视图控制器OnboardingPage,它们都有一个符合协议的视图模型OnboardingPageViewModel协议的视图模型。

\n\n

但遗憾的是上面的代码不起作用:它说不FirstNameViewController确认OnboardingPage协议,因为它的viewModel属性具有类型FirstNameViewModel而不是OnboardingPageViewModel- 即使FirstNameViewModelOnboardingPageViewModel.

\n\n …

swift swift-protocols

2
推荐指数
1
解决办法
158
查看次数

如何对协议及其扩展进行单元测试

我有一个协议,并且在扩展中有它的定义。

我想对定义进行单元测试。

我用谷歌搜索但找不到任何相关内容。

我得到的最接近的是 Mocking with Protocol 或 POP 等。

如果有人可以用示例向我解释,那就太好了。

unit-testing protocols swift swift-protocols protocol-extension

2
推荐指数
1
解决办法
3080
查看次数

无法分配给属性:“class”是“let”常量

let subscriber: SubscriberContextProviding我正在尝试通过简单地直接设置来更新定义为的服务的属性,WatchlistViewModel如下所示:

subscriber.watchlist = watchlist 
Run Code Online (Sandbox Code Playgroud)

相关订户定义:

final class Subscriber: SubscriberContextProviding {
  var watchlist = [String]()
}
Run Code Online (Sandbox Code Playgroud)

但是我收到一条错误消息:Cannot assign to property: 'subscriber' is a 'let' constant 。订阅者服务被声明为 alet并在客户端中初始化init。这是相关的协议部分 & init

protocol SubscriberContextProviding {
  var watchlist: [String] { get set }
}

class WatchlistViewModel: NSObject {
  let subscriber: SubscriberContextProviding

  init(subscriber: SubscriberContextProviding){
    self.subscriber = subscriber
    super.init()
  }
}
Run Code Online (Sandbox Code Playgroud)

但是如果我将协议从上面的协议更改为

protocol SubscriberContextProviding {
  func set(watchlist: [String])
}
Run Code Online (Sandbox Code Playgroud)

我只是将函数定义subscriber

func set(watchlist: [String]){
  self.watchlist …
Run Code Online (Sandbox Code Playgroud)

swift swift-protocols

2
推荐指数
1
解决办法
1522
查看次数

类型不能符合 Decodable 但实际上是

我有一个名为 ObjectAPIModel 的类型,它明确符合 Codable 协议。我还有一个函数,它接收一些数据并调用另一个函数将任何 JSON 解码为指定类型。但是如果我调用decodeJSON(),它会显示一个错误,指出ObjectAPIModel 不符合Decodable。有人可以帮忙吗?

struct ObjectAPIModel: Codable {
    
    let objectID: Int
    var primaryImage: String
    var title: String
    var department: String
}
Run Code Online (Sandbox Code Playgroud)
func decodeJSON<T: Decodable>(data: Data, ofType: T) -> Result<T, APIError> {
        
    let decodedObject = try? JSONDecoder().decode(T.self, from: data)
    if decodedObject == nil {
        return .failure(APIError.emptyResponse)
    } else {
        return .success(decodedObject!)
    }
}
Run Code Online (Sandbox Code Playgroud)
let result = decodeJSON(data: unwrappedData, ofType: ObjectAPIModel)
Run Code Online (Sandbox Code Playgroud)

我收到错误:“类型‘ObjectAPIModel.Type’不能符合‘Decodable’”

swift swift-protocols codable decodable

2
推荐指数
1
解决办法
721
查看次数

在Swift中实现Objective C委托

我有一个Objective C类,其方法如下所示:

@class Client;

@protocol ClientDelegate <NSObject>

@optional
-(void) receivedMessageFromClient : (id) message;

@end

@interface Client : NSObject 

+(id) setup; 
 @property(nonatomic, strong) id <ClientDelegate> clientDelegate;

// more method declarations below
Run Code Online (Sandbox Code Playgroud)

我正在我的Swift类中实现ClientDelegate,如下所示:

class HomeViewController: UIViewController, ClientDelegate {
    var client : AnyObject?
    var delegate: ClientDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()

        client = Client.setup() as! Client
         client.clientDelegate = self
    }

func receivedMessageFromClient(message: AnyObject) {
        print("Message recieved: \(message)")
    }
}
Run Code Online (Sandbox Code Playgroud)

这给了我一个编译错误:

无法分配属性:'self'是不可变的

当我删除线条

client = Client.setup() as! Client
client.clientDelegate = self
Run Code Online (Sandbox Code Playgroud)

代码编译并调用Client类中receivedMessageFromClient的方法,该方法又转发消息,但不调用该方法 …

objective-c swift swift-protocols

1
推荐指数
1
解决办法
5776
查看次数

协议是否可以要求符合类型成为另一种类型的子类型?

例如:我想在协议定义中说,符合它的类还需要子类化UIView或其他自定义类 type MyClass。那可能吗?

swift swift-protocols swift3

1
推荐指数
1
解决办法
105
查看次数

具有关联类型的Swift子协议

我想知道如何在Swift中表达这种类型的关系(例如kotlin中的示例)

interface Index<K, V> {
  fun getAll(key: K): Sequence<V>
}
Run Code Online (Sandbox Code Playgroud)

我试图使用具有关联类型的协议,如下所示:

protocol Index {
    associatedtype Key
    associatedtype Value
    associatedtype Result: Sequence where Sequence.Element == Value

    func getAll(key: Key) -> Result
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用(Associated type 'Element' can only be used with a concrete type or generic parameter base

然后,作为一种解决方法,我尝试了此操作:

protocol Index {
    associatedtype Key
    associatedtype Value

    func get<T: Sequence>(key: Key) -> T where T.Element == Value
}
Run Code Online (Sandbox Code Playgroud)

但这似乎并不是正确/惯用的方法。

只有两个约束:

  1. 序列不能是具体类型
  2. Index上的所有方法都没有有意义的实现

笔记:

  • 将存在一个Sequence特定于每个实现的类/类型Index

我愿意接受任何其他结构性改变!提前致谢。

generics associated-types swift swift-protocols

1
推荐指数
1
解决办法
1823
查看次数

我何时以及为什么会在 Swift 中使用协议?

所以我遇到了协议的主题,我在互联网上搜索了很多答案,但我找不到一个,至少一个解决了我的问题。

所以我明白协议是方法、属性等的“蓝图”,它可以在类或结构中实现,并且它需要符合其要求等,但为什么要使用一个?

我的意思是你也可以在结构本身内创建一个函数。编写协议似乎有点麻烦,然后为了实现所述协议,这次您必须使用更多代码再次编写所有要求。

人们使用协议有什么特别的原因吗?是为了您的代码安全还是出于其他原因?

例如:

在 swift 中,你有 CustomStringConvertible 协议,它有一个必需的计算属性来控制如何将自定义类型表示为可打印的 String 值,但你也可以在你的类中创建一个函数来解决这个问题。您甚至可以在不实现此协议的情况下计算出与此协议相同的属性。

因此,如果有人可以对这个主题有所了解,那就太好了。

先感谢您!

protocols swift swift-protocols customstringconvertible

1
推荐指数
1
解决办法
2431
查看次数