Gleichzeitige Zugriffe auf 0x1c0a7f0f8, aber änderung erfordert den exklusiven Zugriff Fehler auf Xcode 9 beta 4
mein Projekt verwendet sowohl Objective-C und Swift-code. Wenn sich ein Benutzer anmeldet, ruft es aus einer Reihe von apis für die Benutzereinstellung, ich habe eine DataCoordinator.swift-Klasse, die Zeitpläne, die die API-Bedienung und ich diese Anrufe von UserDetailViewController.in der m-Klasse zum laden von Benutzer-Einstellungen. Diese Nutzung gut zu funktionieren, bevor ich meine migriert code Swift 4 mit Xcode 9 beta 4. Nun wenn ich mich Anmelde stürzt er ab, indem er mir diese Fehler in meinem DataCoordinator Klasse. Unten ist ein Beispiel meines DataCoordinator und Viewcontroller-Klasse.
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
}
//Dies ist, wie ich es nenne in meinem viewcontrollers viewDidLoad-Methode
__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
}
}
Ich bin nicht sicher, wie gehen Sie an diese, sah ich einen bug-report an https://bugs.swift.org/browse/SR-5119 aber es scheint behoben zu sein in Xcode 9 beta 3. Jede Hilfe ist willkommen
- Ich sehe das als gut an Xcode 9 beta 5. Kein Problem, pre-beta 4 oder Xcode 8. Immer noch Graben.
- Trotzdem passiert mir das in Xcode 9 Beta 6 🙁 es passiert, wenn ein hinzufügen von einem Beobachter zu einem MPVolumeViews Taste alpha Schlüsselpfad und Abstürze beim Zugriff auf den Kontext, in observeValue(forKeyPath:von:ändern:Objekt:)
- Wissen Sie, in welcher Zeile diese Laufzeit-check ausgelöst wird? Was ist das Objekt an der Adresse
0x1c0a7f0f8
? - Passiert es im GM auch so???
- es scheint trigger @ line get { return preferenceFetchOperations.Zählung }
- ja, das passiert in der GM-Version zu. Im Swift 4 dies ist eine Funktion, um zu vermeiden, gleichzeitige memory access, aber ich bin mir nicht sicher wie Sie gehen über die Festsetzung dieser. Es sagt nicht jede info auf die Methoden zugreifen, gleichzeitig.
- Habe diese mit einer swap () - Aufruf. Boah. Wo war das Papierkorb zu werfen, dass Swift in?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich denke, dass dieser 'bug' ist möglicherweise ein Swift 4 'feature', konkret etwas nennen Sie 'Exklusiven Zugriff auf den Speicher'.
Check-out dieser WWDC video. Rund um die 50-Minuten-Marke, die langhaarige Sprecher erklärt.
https://developer.apple.com/videos/play/wwdc2017/402/?time=233
Könnten Sie versuchen, drehen Sie die thread-sanitizer in Ihrem Schema-Einstellungen, wenn du glücklich bist, es zu ignorieren. Aber der debugger versucht, Ihnen zu sagen eine subtile threading-Problem so ist es wohl eine bessere Verwendung Ihrer Zeit, um zu versuchen, um herauszufinden, warum Sie etwas haben, schreiben in das array an der gleichen Zeit, es ist aus dem gelesen werden soll.
class
gebunden ist oder nicht. Wenn nicht, handelt es sich bei derstruct
Ebene der Einschränkung, auch wenn die runtime-Typ ein Verweistyp ist, nachdem alle. Ich erwarte nicht, dass ppl zu Folgen, w/o Beispiel-code.Unter die Ziel-Build-Einstellungen. Wählen Sie
No Enforcement
fürExclusive Access to Memory
ausSwift Compiler - Code Generation
Nur im Swift-4 und bei Verwendung
.initial
option für Ihre KVO EinstellungenWenn Sie Ihren Kontext, in observeValue Methode, nur machen Sie Ihre Kontext-variable statische. Diese blog-post beschreibt den Fehler im detail.
In Swift 5.0, wird dies das Standardverhalten beim ausführen Ihrer Anwendung in Release-Modus. Vor 5.0 (Swift 4.2.1 von heute und niedriger) dieses Verhalten wird nur dann ausgeführt, wenn im Debug-Modus.
Ihre Anwendung möglicherweise einen Fehler im release-Modus, wenn Sie ignoriert diese Fehlermeldung.
Betrachten Sie dieses Beispiel:
Was ist der Wert von count ist, wenn die print(count) Zeile gedruckt wird? Naja ich weiß es auch nicht und der compiler gibt unvorhersehbare Ergebnisse, wenn Sie diesen code ausführen. Dies ist nicht erlaubt in Swift 4.0 im debug-Modus und im Swift-5.0 stürzt es auch in der runtime.
Quelle: https://swift.org/blog/swift-5-exclusivity/
In meinem Fall, Swift 4 tatsächlich entdeckten wir eine Art von Fehler, ich hätte nicht bemerkt, bis ich anfing, den Aufruf einer Funktion von mehr als einem Ort. Meine Funktion übergeben wurde, ein inout globalen array und es war Referenzierung beide, die parameter und die globalen Namen. Als ich verändert die Funktion zur Referenz nur der parameter, der "gleichzeitigen Zugriffs" Fehler ging Weg.
Rückgabe null in der
numberOfSections
override-Funktion wird dieser Absturz verursachen:Einfache Lösung -
return 1
in der Funktion oben und dannreturn 0
imcollectionView(_:numberOfItemsInSection:)
Funktion.Was ich tun würde, ist das ändern
FetchOperation
zu einemclass
stattstruct
.