标签: swift-extensions

无法在Swift中覆盖NSDictionary的初始化程序

我正在尝试在Swift中扩展类NSDictionary以包含在init()上设置的NSDate.当我添加自定义init()时,我得到编译器错误:

'required'初始化程序'init(dictionaryLiteral :)'必须由'NSDictionary'的子类提供

但是,当我使用自动完成添加初始化程序时,我收到以下错误:

来自扩展的声明无法覆盖

有没有办法覆盖NSDictionary的初始化程序或者Swift只是不能处理它?

这是我的班级:

class DateParam : NSDictionary {
    let date : NSDate

    init(date: NSDate) {
        super.init()
        self.date = date
    }

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    required convenience init(dictionaryLiteral elements: (NSCopying, AnyObject)...) {
        fatalError("init(dictionaryLiteral:) has not been implemented")
    }
}
Run Code Online (Sandbox Code Playgroud)

nsdictionary swift swift-extensions

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

还有其他语言有类似Swift的扩展吗?

在Swift中,扩展是一种在事后定义类成员的方法.或者,你可以说,它是(来自一个全新的)组合函数的奇特方式:

extension Double {
    var mm: Double { return self * 1_000.0 }
    func mm1() -> Double { return self * 1_000.0 }
}

func mm(a: Double) -> Double {
    return a * 1_000.0
}

print("One meter is \(1.mm) milimeters")
print("One meter is \(1.mm1()) milimeters")
print("One meter is \(mm(1)) milimeters")
Run Code Online (Sandbox Code Playgroud)

我从来没有见过这样的东西.在任何其他语言中都有这样的东西吗?

methods member-functions swift swift-extensions

5
推荐指数
2
解决办法
527
查看次数

使用添加默认参数的方法扩展协议

我习惯使用扩展在协议内部使用默认参数,因为协议声明本身不能使用它们,如下所示:

protocol Controller {
   func fetch(forPredicate predicate: NSPredicate?)
}

extension Controller {
   func fetch(forPredicate predicate: NSPredicate? = nil) {
      return fetch(forPredicate: nil)
   }
}
Run Code Online (Sandbox Code Playgroud)

为我工作完美.

现在我有下一个情况,我有一个特定类型的控制器的特定协议:

protocol SomeSpecificDatabaseControllerProtocol {
    //...
    func count(forPredicate predicate: NSPredicate?) -> Int
}
Run Code Online (Sandbox Code Playgroud)

和协议扩展以及控制器的默认方法的实现:

protocol DatabaseControllerProtocol {
    associatedtype Entity: NSManagedObject
    func defaultFetchRequest() -> NSFetchRequest<Entity>
    var context: NSManagedObjectContext { get }
}

extension DatabaseControllerProtocol {
    func save() {
        ...
    }

    func get() -> [Entity] {
        ...
    }

    func count(forPredicate predicate: NSPredicate?) -> Int {
        ...
    }

    //..... …
Run Code Online (Sandbox Code Playgroud)

swift swift-extensions swift-protocols

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

Swift扩展 - 必须在非专用泛型类型'Array'上声明约束扩展

我有一个返回JSON对象数组的API.我已将结构设置为如下所示:

typealias MyModels = [MyModel]

struct MyModel: Codable {
    let field1: String
    let field2: String
    let mySubModel: SubModel?

    enum CodingKeys: String, CodingKey {
        case field1 = "Field1"
        case field2 = "Field2"
        case mySubModel = "MySubModel"
    }
}

struct SubModel: Codable {
    let subModelField1: String
    let subModelField2: String

    enum CodingKeys: String, CodingKey {
        case subModelField1 = "SubModelField1"
        case subModelField2 = "SubModelField2"
    }
}
Run Code Online (Sandbox Code Playgroud)

我想要做的是添加此扩展,提供路径var(NetworkModel协议为API操作提供了一些基本功能):

extension MyModels: NetworkModel {
    static var path = "the/endpoint/path"
}
Run Code Online (Sandbox Code Playgroud)

当base是对象或json键时,我在这种方式设置的其他模型/结构类中没有任何问题.但是,由于这个是不同的,并且只是一个数组,当我在该类中放入该扩展时,我收到此错误:

Constrained extension must be declared on …
Run Code Online (Sandbox Code Playgroud)

collections ios type-alias swift swift-extensions

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

如何为仅在测试中可见的结构创建 init 方法?

我想为我的结构创建一个 init 方法,其中包含一堆用于单元测试的默认值。我不希望主模块能够看到这个 init 方法。

我以为我可以简单地在我的测试类文件中创建结构的扩展,但这不起作用:

Foo.swift(在应用程序目标中):

public struct Foo {

    public let bar: Int

    public init(colour: String) {
        self.bar = colour == "Green" ? 0 : 1
    }

}
Run Code Online (Sandbox Code Playgroud)

FooExtension.swift(在测试目标中):

extension Foo {

    public init(bar: Int = 42) {
        self.bar = bar
    }

}
Run Code Online (Sandbox Code Playgroud)

请注意主文件中的非默认初始化程序,因此 Swift 编译器不会自动为我创建成员初始化程序。也许这与问题有关,也许不是。

Swift 编译器抱怨Cannot assign to 'bar' in 'self'。但是当我将该 init 方法复制到Foo我的主要目标中结构的原始定义中时,它工作正常。无论是否使用默认参数值,我都会得到相同的结果。

这是一个 Swift 编译器错误还是与在一个模块中为另一个定义的结构定义扩展有关?当我尝试在 Playground 中复制它时,一切正常。

我使用 Swift 1.2 和 Xcode 版本 6.4 (6E35b)

swift swift-extensions

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

什么是Java相当于Swift"扩展"?

根据Swift官方文档(Swift扩展文档),Swift扩展看起来像Java枚举.

Swift extensions:

extension Double {
var km: Double { return self * 1_000.0 }
var m: Double { return self }
var cm: Double { return self / 100.0 }
var mm: Double { return self / 1_000.0 }
var ft: Double { return self / 3.28084 }
}

let oneInch = 25.4.mm
print("One inch is \(oneInch) meters")
// prints "One inch is 0.0254 meters"
Run Code Online (Sandbox Code Playgroud)

我试图在Java中表示这个并提出以下代码.这个Java表示是否正确?还是有其他方式代表这个?

public enum LengthMetric {

km(1.0e3), mm(1.0e-3), m(1.0e0);

private final double number; …
Run Code Online (Sandbox Code Playgroud)

java swift swift-extensions

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

通过遵循Swift 2中的协议来扩展类型数组

我想扩展一个类型化数组Array<SomeType>,使其符合协议SomeProtocol。现在我知道您可以扩展如下的类型化数组:

extension Array where Element: SomeType { ... }
Run Code Online (Sandbox Code Playgroud)

您还可以扩展对象以遵循以下协议:

extension Array: SomeProtocol { ...  }
Run Code Online (Sandbox Code Playgroud)

但是我无法弄清楚什么是使类型化数组符合协议的正确语法,例如:

extension (Array where Element: SomeType): SomeProtocol { ... }
Run Code Online (Sandbox Code Playgroud)

任何Swift 2专家都知道该怎么做?

generics swift swift-extensions swift2

4
推荐指数
2
解决办法
832
查看次数

RawRepresentable上的Swift扩展没有可访问的初始化程序

我正在尝试为我的FieldIdentifiable协议创建扩展,只有实现它的枚举具有Int的RawValue.唯一的问题是该return FieldIdItem(rawValue: newValue)行一直显示此错误:

'Self.FieldIdItem' cannot be constructed because it has no accessible initializers
Run Code Online (Sandbox Code Playgroud)

这是一个Swift bug还是我错过了什么?

enum SignUpField: Int, FieldIdentifiable {
  case Email = 0, Password, Username

  typealias FieldIdItem = SignUpField
}

protocol FieldIdentifiable {
  typealias FieldIdItem

  func next() -> FieldIdItem?
  func previous() -> FieldIdItem?
}

extension FieldIdentifiable where Self: RawRepresentable, Self.RawValue == Int {

  func next() -> FieldIdItem? {
    let newValue: Int = self.rawValue+1
    return FieldIdItem(rawValue: newValue)
  }

  func previous() -> FieldIdItem? {
    return FieldIdItem(rawValue: self.rawValue-1)
  }
}
Run Code Online (Sandbox Code Playgroud)

generics enums swift swift-extensions swift-protocols

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

交换键和值的字典扩展 - Swift 4.1

字典扩展 - 交换字典键和值

斯威夫特 4.1,Xcode 9.3

我想创建一个函数来获取Dictionary并返回所述字典,但将其值作为键,将其键作为其各自的值。到目前为止,我已经做了一个函数来做到这一点,但我无法将它变成extensionfor Dictionary


我的功能

func swapKeyValues<T, U>(of dict: [T : U]) -> [U  : T] {
    let arrKeys = Array(dict.keys)
    let arrValues = Array(dict.values)
    var newDict = [U : T]()
    for (i,n) in arrValues.enumerated() {
        newDict[n] = arrKeys[i]
    }
    return newDict
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

 let dict = [1 : "a", 2 : "b", 3 : "c", 4 : "d", 5 : "e"]
 let newDict = swapKeyValues(of: dict)
 print(newDict) //["b": 2, "e": …
Run Code Online (Sandbox Code Playgroud)

swap dictionary function swift swift-extensions

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

在 Swift 中,协议扩展是否允许函数体?

我正在阅读一个教程,我注意到作者扩展了他们的称为 Activity 的协议,并在他们的代码中编写了函数的主体。这确实可以编译,但我的印象是协议仅显示方法签名,或者如果它确实实现了主体,那么它将是一个变异函数。下面的代码没有对其函数之一使用变异,但它仍然可以运行并且可以工作!有人可以解释这种现象或确认协议扩展可以有方法体吗?

import CareKit
import SwiftyJSON

enum ActivityType: String {
        case Intervention
        case Assessment
}

enum ScheduleType: String {
    case Weekly
    case Daily

}

enum StepFormat : String {
    case Scale
    case Quantity
}

protocol Activity {

    var identifier : String  { get set}
    var groupIdentifier : String  { get set}
    var title : String  { get set}
    var colour : UIColor?  { get set}
    var text : String  { get set}
    var startDate : Date  { get set} …
Run Code Online (Sandbox Code Playgroud)

swift swift-extensions swift-protocols

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