我想了解为什么使用结构会导致此问题,而类却没有。将元素追加到数组并让观察者加载表时遇到了问题。这是代码:
Order.swift-订购商品
struct Order {
var menuItems: [MenuItem]
init(menuItems: [MenuItem] = []) {
self.menuItems = menuItems
}
}
MenuController.swift-包含订单和共享实例
struct MenuController {
static var shared: MenuController = MenuController()
static let orderNotification = Notification.Name("MenuController.orderUpdated")
var order = Order() {
didSet {
NotificationCenter.default.post(name: MenuController.orderNotification,
object: nil)
}
}
MenuItemViewController.swift-订购屏幕
@IBAction func orderButtonTapped(_ sender: UIButton) {
MenuController.shared.order.menuItems.append(menuItem)
}
OrderTableViewController.swift-物品订购屏幕
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(tableView,
selector: #selector(UITableView.reloadData),
name: MenuController.orderNotification, object: nil)
}
...
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return MenuController.shared.order.menuItems.count //Simultaneous access error thrown here
}
现在,我犯了一个设计错误,即MenuController应该是类而不是结构,因为我们要在整个应用程序中共享MenuController实例,因此它应该是引用类型。使用类解决了同时访问问题。
我很困惑的是: 为什么当观察者尝试加载tableView时,值类型(结构)的MenuController会导致此同时访问问题。
希望有人可以解释。 TIA!
答案 0 :(得分:2)
它与“对内存的独占访问权”有关,并在此处进行了很好的解释:
Simultaneous accesses to 0x1c0a7f0f8, but modification requires exclusive access error on Xcode 9 beta 4
简短版本:var不能同时“可读”和“可写”。当set
操作开始时,变量是“可写的”,如果在变量var仍然是“可写”的情况下发生get
操作(“可读”),则会触发异常。
在didSet
上,var是“可写的”。如果didSet
中的操作导致调用堆栈中的某处导致正在读取的var,它将触发异常。
即使没有didSet
,如果您具有设置var并随后发布通知的变异函数,该通知的观察者将尝试读取该通知,则将触发相同的异常。
答案 1 :(得分:0)
我的情况与@bauerMusic的回答不同。
我将相关代码放在DispatchQueue.main.async
块(主线程)中,此问题已解决。
我的情况也是一个线程问题。