Accès simultané à 0x1c0a7f0f8, mais la modification nécessite un accès exclusif d'erreur sur Xcode 9 beta 4
mon projet utilise à la fois Objective-C et Swift code. Lorsqu'un utilisateur se connecte, il appelle un ensemble d'api pour la préférence de l'utilisateur, j'ai un DataCoordinator.swift classe où les horaires le fonctionnement de l'API et je en faire des appels à partir de UserDetailViewController.m classe de charger les préférences de l'utilisateur. Cette utilisation pour le travail bien avant que j'ai migré mon code Swift 4 à l'aide de Xcode 9 beta 4. Maintenant, quand je me connecte il se bloque en me donnant cette erreur dans mon DataCoordinator classe. Ci-dessous est un échantillon de mes DataCoordinator et Viewcontroller classe.
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
}
//C'est comme ça que j'appelle dans mon viewcontrollers méthode 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
}
}
Je ne suis pas sûr de la façon de procéder sur ce, j'ai vu un rapport de bug à https://bugs.swift.org/browse/SR-5119 mais il semble être fixe dans Xcode 9 beta 3. Toute aide est appréciée
Passe encore pour moi dans Xcode 9 Beta 6 🙁 il arrive quand un ajouter un observateur à un MPVolumeViews bouton alpha chemin d'accès clé et se bloque lors de l'accès au contexte dans observeValue(forKeyPath:de:changement:objet:)
Savez-vous à quelle ligne de ce moment de l'exécution est déclenchée? Quel est l'objet à l'adresse
0x1c0a7f0f8
?Est-ce qui se passe dans le GM??
il semble déclencher @ line get { return preferenceFetchOperations.count }
OriginalL'auteur Gamerlegend | 2017-07-31
Vous devez vous connecter pour publier un commentaire.
Je pense que ce " bug " est peut-être un Swift 4 'fonction', spécifiquement quelque chose qu'ils appellent "l'accès Exclusif à la Mémoire".
Découvrez cette WWDC vidéo. Aux alentours de 50 minutes, le poil long, haut-parleur, l'explique.
https://developer.apple.com/videos/play/wwdc2017/402/?time=233
Vous pouvez essayer de tourner le fil de désinfectant dans votre régime paramètres si vous êtes heureux de l'ignorer. Cependant, le débogueur est d'essayer de vous parler d'un subtil problème thread donc c'est probablement une meilleure utilisation de votre temps pour essayer de comprendre pourquoi vous avez quelque chose d'écrit au tableau en même temps, il est en cours de lecture.
class
lié ou pas. Lorsqu'il n'est pas, il agit avec lastruct
niveau de restriction, même si le runtime type est un type de référence, après tout. Je ne m'attends pas ppl pour suivre w/o exemple de code.J'ai trouvé votre commentaire vraiment utile dans mon cas . J'ai une question, avez-vous un livre qui traite ce sujet que vous avez mentionné: "...ça dépend si le type de protocole est de classe lié ou pas. Lorsqu'il n'est pas, il agit avec la structure au niveau de ..."
OriginalL'auteur Mark Bridges
Sous la cible Paramètres de construction. Sélectionnez
No Enforcement
pourExclusive Access to Memory
deSwift Compiler - Code Generation
OriginalL'auteur geek1706
Seulement dans Swift 4 et lors de l'utilisation de
.initial
option pour votre KVO ParamètresSi vous vérifiez votre contexte dans observeValue méthode, il suffit de faire votre variable de contexte statique. Cette post de blog décrit ce bug en détail.
Yep, court mais regarde comme il convient vraiment de nos lignes directrices en vigueur. J'ai supprimé mon commentaire et merci pour le heads up 😉
Merci! Si votre code est de s'écraser observeValue autour de la variable de contexte, c'est certainement la réponse!
OriginalL'auteur Ralf Hundewadt
Dans mon cas, Swift 4 en fait découvert un genre de bug que je n'aurais pas remarqué jusqu'à ce que j'ai commencé à l'appel d'une fonction de plus d'un endroit. Ma fonction était passé un inout tableau global et il faisait référence à la fois que le paramètre et le nom global. Quand j'ai changé la fonction de référence, seul le paramètre "accès simultané" erreur de s'en alla.
OriginalL'auteur KenM
Dans Swift 5.0, ce sera le comportement par défaut lors de l'exécution de votre application dans mode de Libération. Avant 5.0 (Swift 4.2.1 dès aujourd'hui et inférieur) ce comportement est seulement en cours d'exécution en mode Débogage.
Votre application peut échouer en mode release, si vous avez ignoré cette erreur.
Considérons cet exemple:
Quelle est la valeur de compteur, lors de l'impression(comte) de la ligne est imprimé? Eh bien, je ne sais pas non plus et le compilateur donne unpredicatable résultats lorsque vous exécutez ce code. Ce n'est pas autorisé dans Swift 4.0 en mode debug et en Swift 5.0, il se bloque, même dans l'exécution.
Source: https://swift.org/blog/swift-5-exclusivity/
OriginalL'auteur J. Doe
Retour de zéro dans le
numberOfSections
remplacer la fonction sera la cause de ce crash:Solution Simple -
return 1
dans la fonction ci-dessus, puisreturn 0
dans lecollectionView(_:numberOfItemsInSection:)
fonction.OriginalL'auteur JonJ
Ce que j'ai à faire est de changer
FetchOperation
à unclass
au lieu destruct
.OriginalL'auteur Tai Le