标签: protocol-extension

Swift协议仅由特定类实现

我想创建一个只被特定类及其子类迅速采用的协议。我知道我可以使用这样的协议扩展

  protocol PeopleProtocol: class {
   }

   extension PeopleProtocol where Self: People {
   }
Run Code Online (Sandbox Code Playgroud)

但是,将在我的协议中使用的init方法将是将由类或其子类实现的方法,并且仅返回某些特定类型的对象。

这样的事情。

protocol PeopleProtocol: class {
   init() -> People
}
Run Code Online (Sandbox Code Playgroud)

或者我可以做这样的事情

extension PeopleProtocol where Self : People {
   init()
}
Run Code Online (Sandbox Code Playgroud)

但是有两个问题,

  1. 在第一种方法中,如果我将init方法放在协议中,则不允许像-> People在第一种方法中那样在其中放置return语句。

  2. 在第二种方法中,我必须在协议扩展中提供一个函数主体,因此这件事毫无疑问,因为我不知道该通用实现返回哪种特定类型。

因此,任何建议如何调用init方法并执行以下任一操作:

  1. 让该协议(不是协议扩展)仅由特定的类及其子类实现。
  2. 或者从协议扩展方法返回某个实例的实例,而不给出其主体。

protocols swift protocol-extension

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

具有约束类型的Swift协议扩展约束到集合,不能使用下标

我正在尝试编写符合集合协议的协议,它有一个associatedType - Object和一个属性对象.

protocol DDCDataSource: Collection
{
    associatedtype Object
    var object: Object {get set}
}
Run Code Online (Sandbox Code Playgroud)

我想为Object也符合Collection协议的情况添加一些默认功能,即直接返回Object对这些必需Collection属性和函数的实现.除了Collection对下标的要求外,它似乎都有效.

无法使用类型为"Self.Object.Index"的索引下标"Self.Object"类型的值

在此输入图像描述

extension DDCDataSource where Object: Collection
{
    typealias Index = Object.Index

    var startIndex: Object.Index {
        get {
            return object.startIndex
        }
    }

    var endIndex: Object.Index {
        get {
            return object.endIndex
        }
    }

    subscript(position: Object.Index) -> Element
    {
        return object[position]
    }

    func index(after i: Object.Index) -> Object.Index {
        return object.index(after: i)
    }
}
Run Code Online (Sandbox Code Playgroud)

generics swift swift-protocols protocol-extension swift3.2

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

当某些协议功能改变其签名时,我可以强制编译器失败吗?

有没有办法将某些Swift函数标记为实现某些协议函数,以便在协议的签名发生更改时,编译器可以将实现标记为错误.

例如,考虑这个例子,我有一个实例Foo协议的默认实现UIViewController,我想覆盖它作为Bar子类的自定义类UIViewController.

// V1
protocol Foo {
    func number() -> Int
}

extension Foo where Self: UIViewController {
    func number() -> Int {
        return 0
    } 
}

// Overrides the default implementation
extension Bar: Foo {
    func number() -> Int {
        return 1
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,该协议演变为:

// V2
protocol Foo {
    func numberV2() -> Int
}

extension Foo where Self: UIViewController {
    func numberV2() -> Int {
        return 0
    } 
}

// …
Run Code Online (Sandbox Code Playgroud)

xcode swift protocol-extension

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

调用协议扩展初始化程序

我正在尝试构建一组共享通用初始化代码的类。除了继承之外,我认为协议是可行的方法。虽然协议和协议扩展对我来说可以使用实例和静态方法,但我在使其与初始值设定项一起使用时遇到了一些麻烦。

假设我们有这个协议:

protocol CloudServiceWrapper {

    static var isConfigured: Bool { get }

    init()

    func initialize()

}
Run Code Online (Sandbox Code Playgroud)

现在假设我们要在协议扩展中添加isConfigured和的默认实现:init()

extension CloudServiceWrapper {

    static var isConfigured: Bool {
        get {
            return true
        }
    }

    init() {
        print("Initializing generic CloudServiceWrapper")
        self.init()
        if Self.isConfigured {
            initialize()
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

最后,让我们有一个类实现此协议并尝试从其默认实现中受益:

class OneDriveWrapper: CloudServiceWrapper {

    required init() {
        // CloudServiceWrapper() // error: protocol type 'CloudServiceWrapper' cannot be instantiated
        // self = CloudServiceWrapper.init() // error: cannot assign to value: 'self' is immutable
        // super.init() …
Run Code Online (Sandbox Code Playgroud)

ios swift swift-protocols protocol-extension

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

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

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

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

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

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

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

unit-testing protocols swift swift-protocols protocol-extension

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

Swift 中对数值数组求和的计算属性

书中的任务说:在不调用reduce(_: _:)方法的情况下,通过添加一个名为sum的计算属性来对数字序列求和。您应该能够像这样使用它:

[3, 7, 7].sum            // 17
[8.5, 1.1, 0.1].sum      // 9.7
Run Code Online (Sandbox Code Playgroud)

作者提示:在开发人员文档中检查 Int 和 Double 遵循哪些协议,以及这些协议继承自哪些协议。在下面的代码中,我只是结合了我找到的两个解决方案,但它仍然包含方法reduce。如果您可以帮助我了解如何解决这个问题/开发人员文档的哪一部分提供了线索。另外,如何避免当前代码中的错误/在封闭范围内应用可能的解决方案。

extension Sequence where Element: Numeric {
    var sum: Any {
        return reduce(0, +)
    }
}

[3, 7, 7].sum
[8.5, 1.1, 0.1].sum
[1...4].sum // Error: Property 'sum' requires that 'ClosedRange<Int>' conform to 'Numeric'
Run Code Online (Sandbox Code Playgroud)

arrays swift computed-properties protocol-extension protocol-inheritance

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

Swift 2协议扩展使用

我正试图用Swift 2赶上这种面向协议的编程酷,但我现在已经迷失了.

我正在尝试将该理论应用于实际用例,所以让我们从最明显的开始:

假设我有一个UITextField并且我希望有许多协议(例如phone,numeric,lengthLimited ......)符合UITextFieldDelegate并覆盖该textField:shouldChangeCharactersInRange:replacementString方法以完成所需的行为.

甚至可以使用带有此扩展名的"Extensions.swift"文件并将所需的协议分配给UITextField(例如,numeric,lengthLimited)?那将非常有用.如果是这样,有没有办法将协议分配给一个UITextField插座,或者我需要子类化UITextField并使其符合所需的协议?如果是这种情况,那么我没有看到使用协议扩展而不是旧的子类化的太多优势.

protocols ios swift protocol-extension

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