objective not developer could apple objective-c crash ios11 swift4 xcode9-beta

objective c - not - Acceso simultáneo a 0x1c0a7f0f8, pero la modificación requiere un error de acceso exclusivo en Xcode 9 beta 4



apple developer (3)

mi proyecto usa código Objective-C y Swift. Cuando un usuario inicia sesión, llama a un conjunto de apis para la preferencia del usuario, tengo una clase DataCoordinator.swift que programa la operación de la API y realizo estas llamadas desde la clase UserDetailViewController.m para cargar las preferencias del usuario. Este uso funciona bien antes de migrar mi código a Swift 4 usando Xcode 9 beta 4. Ahora, cuando inicio sesión, falla colocándome este error en mi clase DataCoordinator. A continuación hay una muestra de mi clase DataCoordinator y Viewcontroller.

DataCoordinator.swift import UIKit @objcMembers class DataCoordinator: NSObject { //MARK:- Private fileprivate var user = myDataStore.sharedInstance().user fileprivate var preferenceFetchOperations = [FetchOperation]() fileprivate func scheduleFetchOperation(_ operation:FetchOperation, inFetchOperations operations:inout [FetchOperation]) { guard operations.index(of: operation) == nil else { return } operations.append(operation) } fileprivate func completeFetchOperation(_ fetchOperation:FetchOperation, withError error:Error?, andCompletionHandler handler:@escaping FetchCompletionHandler) { func removeOperation(_ operation:FetchOperation, fromOperations operations:inout [FetchOperation]) { if operations.count > 0 { operations.remove(at: operations.index(of: fetchOperation)!) handler(error) } } if preferenceFetchOperations.contains(fetchOperation) { removeOperation(fetchOperation, fromOperations: &preferenceFetchOperations) } } fileprivate func schedulePreferencesFetchOperation(_ serviceName:String, fetch:@escaping FetchOperationBlock){ let operation = FetchOperation(name: serviceName, fetch: fetch); scheduleFetchOperation(operation, inFetchOperations: &preferenceFetchOperations) } fileprivate func runOperationsIn(_ fetchOperations:inout [FetchOperation]) { for var operation in fetchOperations { guard operation.isActivated == false else { continue } operation.isActivated = true operation.execute() } } //MARK:- Non-Private typealias FetchCompletionHandler = (_ error:Error?)->Void var numberOfPreferencesFetchCalls:Int { get { return preferenceFetchOperations.count } } // MARK: - func fetchPreferences(_ completionHandler:@escaping FetchCompletionHandler) -> Void { defer { runOperationsIn(&preferenceFetchOperations) } schedulePreferencesFetchOperation("com.fetchPreferences.type1") {[unowned self] (operation:FetchOperation) in WebServiceManager.getType1Detail(for: user) {[unowned self] (error) in self.completeFetchOperation(operation, withError: error, andCompletionHandler: completionHandler) } } schedulePreferencesFetchOperation("com.fetchPreferences.type2") {[unowned self] (operation:FetchOperation) in WebServiceManager.getType2Detail(for: user) {[unowned self] (error) in self.completeFetchOperation(operation, withError: error, andCompletionHandler: completionHandler) } } schedulePreferencesFetchOperation("com.fetchPreferences.type3") {[unowned self] (operation:FetchOperation) in WebServiceManager.getType3Detail(for: user) {[unowned self] (error) in self.completeFetchOperation(operation, withError: error, andCompletionHandler: completionHandler) } } schedulePreferencesFetchOperation("com.fetchPreferences.type4") {[unowned self] (operation:FetchOperation) in WebServiceManager.getType4Detail(for: user) {[unowned self] (error) in self.completeFetchOperation(operation, withError: error, andCompletionHandler: completionHandler) } } } } // MARK:- Fetch Operation Struct private typealias FetchOperationBlock = (_ operation:FetchOperation)->Void private struct FetchOperation:Hashable { fileprivate var runToken = 0 fileprivate let fetchBlock:FetchOperationBlock let name:String! var isActivated:Bool { get { return runToken == 0 ? false : true } mutating set { if runToken == 0 && newValue == true { runToken = 1 } } } fileprivate var hashValue: Int { get { return name.hashValue } } func execute() -> Void { fetchBlock(self) } init (name:String, fetch:@escaping FetchOperationBlock) { self.name = name self.fetchBlock = fetch } } private func ==(lhs: FetchOperation, rhs: FetchOperation) -> Bool { return lhs.hashValue == rhs.hashValue }

// Así es como lo llamo en mi viewcontrollers método viewDidLoad

__weak UserDetailViewController *weakSelf = self; [self.dataCoordinator fetchPreferences:^(NSError * _Nullable error) { if (error == nil) { [weakSelf didFetchPrefrences]; } else { // handle error } }]; //completion response - (void)didFetchPrefrences { //when api calls complete load data if (self.dataCoordinator.numberOfPreferencesFetchCalls == 0) { //Load details } }

No estoy seguro de cómo proceder con esto, vi un informe de error en https://bugs.swift.org/browse/SR-5119 pero parece estar corregido en Xcode 9 beta 3. Cualquier ayuda es apreciada


Creo que este ''error'' puede ser una ''característica'' de Swift 4, específicamente algo que ellos llaman ''Acceso exclusivo a la memoria''.

Mira este video de WWDC. Alrededor de los 50 minutos, el hablante de pelo largo lo explica.

https://developer.apple.com/videos/play/wwdc2017/402/?time=233

Podría intentar desactivar el desinfectante de hilos en la configuración de su esquema si está feliz de ignorarlo. Sin embargo, el depurador está tratando de informarle acerca de una emisión sutil de subprocesos, por lo que es probablemente un mejor uso de su tiempo para tratar de averiguar por qué tiene algo escrito en su matriz al mismo tiempo que se lee.


En mi caso, Swift 4 realmente descubrió un tipo de error que no habría notado hasta que comencé a llamar a una función desde más de un lugar. Mi función pasó una matriz global inout y hacía referencia tanto a ese parámetro como a su nombre global. Cuando cambié la función para hacer referencia solo al parámetro, el error de "acceso simultáneo" desapareció.


Swift 4: si comprueba su contexto en el método observeValue, simplemente establezca su variable de contexto. Esta publicación de blog describe este problema en detalle.