标签: swift-structs

swift - 我可以从自定义init方法调用struct default memberwise init吗?

如果我创建一个没有的swift结构init,那么我可以调用编译器生成的默认成员初始化器,如下所示:

struct OrderFill {
    let price:Int
    let qty: Int
    let timeStamp: NSDate
}
let o = OrderFill(price: 2, qty: 1, timeStamp: someDate)
Run Code Online (Sandbox Code Playgroud)

我想要做的是创建一个方便的init方法来从字典反序列化,然后字典链接到默认的成员init.就像是

struct OrderFill {
    let price:Int
    let qty: Int
    let timeStamp: NSDate

    init(dict:[String:AnyObject]) throws {
        self.init(
            price: dict["price"] as! Int
            qty: dict["qty"] as! Int
            timeStamp: try parseDate(dict["ts"] as! String)
    }
}
let o = OrderFill(someDict)
Run Code Online (Sandbox Code Playgroud)

当我尝试编写这段代码时,编译器(Xcode 7.2)在调用中给出了错误"额外参数'数量',好像它没有看到默认的成员并试图递归调用 init(dictionary)

我可以编写自己的成员init,或者我可以直接从我的分配属性init(dictionary),但如果我可以链接调用它会很好.有没有办法在swift中做到这一点?

swift swift-structs

33
推荐指数
2
解决办法
8623
查看次数

为什么[SomeStruct]不能转换为[Any]?

考虑以下:

struct SomeStruct {}

var foo: Any!
let bar: SomeStruct = SomeStruct()

foo = bar // Compiles as expected

var fooArray: [Any] = []
let barArray: [SomeStruct] = []

fooArray = barArray // Does not compile; Cannot assign value of type '[SomeStruct]' to type '[Any]'
Run Code Online (Sandbox Code Playgroud)

我一直试图找到这背后的逻辑,但没有运气.值得一提的是,如果将结构更改为类,则可以完美地运行.

总是可以添加一个变通方法并映射fooArray的每个对象并将它们转换为Any类型,但这不是问题.我正在寻找一个解释为什么这样做的样子.

有人可以解释一下吗?

这个问题让我想到了这个问题.

arrays swift swift-structs swift2.2

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

类和结构闭包中的Swift可变结构表现不同

我有一个类(A),它有一个struct变量(S).在这个类的一个函数中,我在struct变量上调用一个mutating函数,这个函数需要一个闭包.此闭包的主体检查struct变量的name属性.

结构的变异函数依次调用某个类(B)的函数.这个类的函数再次关闭.在这个闭包的主体中改变结构,即更改name属性,并调用第一个类提供的闭包.

当我们检查struct的name属性时调用第一个类(A)闭包时,它永远不会被更改.

但是在第2步中,如果我使用结构(C)而不是类B,我会看到内部类A的闭包结构实际上已经改变了.以下是代码:

class NetworkingClass {
  func fetchDataOverNetwork(completion:()->()) {
    // Fetch Data from netwrok and finally call the closure
    completion()
  }
}

struct NetworkingStruct {
  func fetchDataOverNetwork(completion:()->()) {
    // Fetch Data from netwrok and finally call the closure
    completion()
  }
}

struct ViewModelStruct {

  /// Initial value
  var data: String = "A"

  /// Mutate itself in a closure called from a struct
  mutating func changeFromStruct(completion:()->()) {
    let networkingStruct = NetworkingStruct()
    networkingStruct.fetchDataOverNetwork {
      self.data = "B"
      completion()
    }
  } …
Run Code Online (Sandbox Code Playgroud)

mutable mvvm ios swift swift-structs

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

原子属性包装器仅在声明为类时才有效,而不是结构体

我在 Swift 中创建了一个“锁”,并为我的 Swift 类创建了一个使用该锁的 Atomic 属性包装器,因为 Swift 缺少 ObjC 的atomic属性属性。

当我在启用线程清理器的情况下运行我的测试时,它总是捕获使用我的 Atomic 属性包装器的属性上的数据竞争。

唯一有效的是将属性包装器的声明更改为一个类而不是一个结构体,这里的主要问题是:为什么它有效!

print在属性包装器中添加了s 并添加了 lockinit来跟踪创建的对象数量,它与 struct/class 相同,尝试在另一个项目中重现该问题,但也没有用。但是我会添加与问题类似的文件,并让我知道它为什么起作用的任何猜测

public class SwiftLock {

    init() { }

   public func sync<R>(execute: () throws -> R) rethrows -> R {
    objc_sync_enter(self)
    defer { objc_sync_exit(self) }
    return try execute()
    }
}
Run Code Online (Sandbox Code Playgroud)

原子属性包装器

@propertyWrapper struct Atomic<Value> {
    let lock: SwiftLock
    var value: Value

    init(wrappedValue: Value, lock: SwiftLock=SwiftLock()) {
        self.value = wrappedValue
        self.lock = …
Run Code Online (Sandbox Code Playgroud)

ios swift ios-multithreading swift-structs property-wrapper

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

Swift 2.2 MVVM视图模型作为可变结构不在视图控制器中维护状态

我很清楚Swift中值类型和引用类型之间的区别,并且意识到值类型被设计为不可变的用法.但结构特别有能力改变自己,这是我的担忧.如何有效地使用这些变异的struct值类型,以便它们保持其状态或变化.

我的问题是,在iOS应用程序的MVVM设计中应该将模型视为类还是结构?由于视图模型包含模型/模型列表,并且这些模型实例可以随时间变化(例如,视图模型从Web服务请求获取更多模型实例并添加到其模型数组中),视图控制器的视图模型如何更新这种变化.这是一个伪示例,但首先是一些注意事项和简要说明:

  • 我这里没有使用任何绑定.(没有RxSwift).
  • 没有KVO,我正在使用委托或完成处理程序设计.

例:

  • 视图控制器具有视图模型的实例.当它出现时,它要求视图模型从Web服务获取数据.
  • View模型触发服务,并在完成处理程序关闭中获得响应
  • 在此闭包视图模型中,将一些模型实例添加到其模型数组中.
  • View模型调用视图控制器的完成处理程序以通知服务请求的成功或错误.
  • View Controller对视图模型进行一些验证,然后相应地执行UI操作.

查看型号:

 struct DummyViewModel {

  private var ints:[Int] = []

  var count: Int {
    return ints.count
  }

  init() {}

  mutating func fetchData(completionHandler:(NSError? ) -> Void) {
    Networking.getDataFromRemote() { response in
          self.ints.append(1)
          completionHandler(nil)
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

查看控制器:

class DummyViewController: UIViewController{
  private var dummyViewModel: DummyViewModel?

  override func viewDidLoad() {
    super.viewDidLoad()

    /// Setup the view model
    dummyViewModel = DummyViewModel()
  }

  override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    loadData()
  }
} …
Run Code Online (Sandbox Code Playgroud)

value-type mvvm ios swift swift-structs

7
推荐指数
0
解决办法
492
查看次数

Swift结构:为单个属性处理多种类型

我正在使用Swift 4并尝试解析一些JSON数据,这些数据显然在某些情况下可以为同一个键具有不同的类型值,例如:

{
    "type": 0.0
}
Run Code Online (Sandbox Code Playgroud)

{
    "type": "12.44591406"
}
Run Code Online (Sandbox Code Playgroud)

我实际上坚持定义我,struct因为我无法弄清楚如何处理这种情况,因为

struct ItemRaw: Codable {
    let parentType: String

    enum CodingKeys: String, CodingKey {
        case parentType = "type"
    }
}
Run Code Online (Sandbox Code Playgroud)

投掷"Expected to decode String but found a number instead.",当然,

struct ItemRaw: Codable {
    let parentType: Float

    enum CodingKeys: String, CodingKey {
        case parentType = "type"
    }
}
Run Code Online (Sandbox Code Playgroud)

因此投掷"Expected to decode Float but found a string/data instead.".

在定义我的时候如何处理这个(和类似的)情况struct呢?

json data-structures swift swift-structs swift4

7
推荐指数
2
解决办法
3256
查看次数

Swift 4.2) 使用 for_in/forEach 改变结构数组与按索引访问

我正在尝试修改数组中的结构元素。我发现您可以通过按索引访问(迭代)结构来做到这一点,但如果您使用“for in”循环或 forEach{},则不能。

struct Person
{
  var age = 0
  var name = "James"
}

var personArray = [Person]()
personArray += [Person(), Person(), Person()]


personArray.forEach({$0.age = 10}) // error: "Cannot assign to property: '$0' is immutable"

for person in personArray { 
  person.age = 10 // error: "Cannot assign to property: 'person' is a 'let' constant"
}


for index in personArray.indices {
  personArray[index].age = 10 // Ok
}
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下吗?

arrays swift swift-structs

6
推荐指数
2
解决办法
3998
查看次数

swift中的变异结构函数是否会创建一个新的self副本?

我喜欢swift中的值语义,但我担心变异函数的性能.假设我们有以下内容struct

struct Point {
   var x = 0.0
   mutating func add(_ t:Double){
      x += t
   }
}
Run Code Online (Sandbox Code Playgroud)

现在假设我们创建一个Point并将其变异为:

var p = Point()
p.add(1)
Run Code Online (Sandbox Code Playgroud)

现在内存中的现有结构变异,或者被struct替换为新的实例

self = Point(x:self.x+1)
Run Code Online (Sandbox Code Playgroud)

performance struct swift swift-structs

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

在结构中快速记忆/缓存惰性变量

我喝了Swift中的struct / value koolaid。现在我有一个有趣的问题,我不知道该如何解决。我有一个结构是一个容器,例如

struct Foo {
    var bars:[Bar]
}
Run Code Online (Sandbox Code Playgroud)

在对此进行编辑时,我会创建副本,以便保留撤消堆栈。到目前为止,一切都很好。就像显示的好教程一样。不过,我与此人一起使用了一些派生属性:

struct Foo {
    var bars:[Bar]

    var derivedValue:Int {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

在最近的分析中,我注意到a)计算派生Value的计算是一种昂贵/冗余的b)在各种用例中并不总是必须进行计算。

按照我经典的OOP方式,我会将其设置为记忆/惰性变量。基本上,在调用之前将其设置为零,对其进行一次计算并存储,然后在以后的调用中返回所述结果。由于我遵循的是“制作副本以进行编辑”模式,因此不变性不会被破坏。

但是我无法弄清楚如果是struct则如何应用这种模式。我可以做这个:

struct Foo {
    var bars:[Bar]
    lazy var derivedValue:Int = self.computeDerivation()
}
Run Code Online (Sandbox Code Playgroud)

它起作用,直到结构引用该值本身,例如

struct Foo {
    var bars:[Bar]
    lazy var derivedValue:Int = self.computeDerivation()

    fun anotherDerivedComputation() {
        return self.derivedValue / 2
    }
}
Run Code Online (Sandbox Code Playgroud)

此时,编译器会抱怨,因为anotherDerivedComputation正在引起接收方的更改,因此需要进行标记mutating。使访问器被标记为变异只是感觉不对。但是对于咧嘴笑,我尝试了一下,但是这带来了一系列新的问题。现在任何我有表达的地方

XCTAssertEqaul(foo.anotherDerivedComputation(), 20)
Run Code Online (Sandbox Code Playgroud)

编译器抱怨,因为参数隐式是一个不变的let值,而不是var。

我是否缺少一种具有延迟/惰性/缓存成员的结构的模式?

memoization swift swift-structs

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

如何使用 Swift 结构正确解码嵌套的 JSON 对象

意图:

通过Coinmarketcap API接收加密货币价格数据,将其解码为 SWIFT 中的自定义结构,并可能将该数据存储在数据库(CoreData 或 SQLite)中。

语境:

我收到以下错误JSONDecoder().decode

Error serializing json: typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "status", intValue: nil), _DictionaryCodingKey(stringValue: "credit_count", intValue: nil)], debugDescription: "Expected to decode Dictionary<String, Any> but found a number instead.", underlyingError: nil))
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 如何正确解释该错误?我解码错了什么?
  2. 我收到的数据格式是否正确?看起来不像是正确的 JSON。

编码:

import UIKit
import PlaygroundSupport


// Defining structures

struct RootObject: Decodable {
    let status: [String: StatusObject?]
    let data: DataObject?
}

struct StatusObject: Decodable {
    let credit_count: Int?
    let elapsed: Int?
    let error_code: Int?
    let timestamp: String? …
Run Code Online (Sandbox Code Playgroud)

json swift swift-dictionary swift-structs

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