2017-07-31 20 views
7

dự án của tôi sử dụng cả mã Objective-C và Swift. Khi người dùng đăng nhập, nó gọi một tập hợp các apis cho sở thích của người dùng, tôi có một lớp DataCoordinator.swift lên lịch cho hoạt động API và tôi thực hiện cuộc gọi này từ lớp UserDetailViewController.m để tải các sở thích của người dùng. Việc sử dụng này hoạt động tốt trước khi tôi chuyển mã của mình sang Swift 4 bằng cách sử dụng Xcode 9 beta 4. Bây giờ khi tôi đăng nhập nó bằng cách cho tôi lỗi này trong lớp DataCoordinator của tôi. Dưới đây là một ví dụ về lớp DataCoordinator và lớp Viewcontroller của tôi.Truy cập đồng thời vào 0x1c0a7f0f8, nhưng sửa đổi yêu cầu lỗi truy cập độc quyền trên Xcode 9 beta 4

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 
} 

// Đây là cách tôi gọi nó trong viewcontrollers tôi phương pháp 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 

    } 

} 

Tôi không chắc chắn làm thế nào để tiến hành về vấn đề này, tôi thấy một báo cáo lỗi tại https://bugs.swift.org/browse/SR-5119 nhưng nó có vẻ là cố định trong Xcode 9 beta 3. Bất kỳ trợ giúp nào được đánh giá cao

+0

Tôi thấy điều này cũng trên Xcode 9 beta 5. Không phải là vấn đề pre-beta 4 hoặc là Xcode 8. Tuy nhiên đào. – pho0

+0

Vẫn xảy ra với tôi trong Xcode 9 Beta 6: (nó xảy ra khi thêm một người quan sát vào một nút MPVolumeViews alpha keypath và tai nạn khi truy cập vào bối cảnh trong observValue (forKeyPath: of: change: object :) – fruitcoder

+0

Bạn có biết ở dòng nào không Đối tượng ở địa chỉ '0x1c0a7f0f8' là gì? – Sparga

Trả lời

10

Tôi nghĩ 'lỗi' này có thể là tính năng Swift 4 ', đặc biệt là một cái gì đó mà họ gọi là' Truy cập độc quyền vào bộ nhớ '.

Xem video WWDC này. Khoảng 50 phút đánh dấu, người nói tóc dài giải thích nó.

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

Bạn có thể thử chuyển sang các chủ đề khử trùng trong cài đặt chương trình của bạn nếu bạn hài lòng để bỏ qua nó. Tuy nhiên, trình gỡ lỗi đang cố gắng cho bạn biết về một vấn đề luồng tinh tế, vì vậy có thể sử dụng thời gian của bạn tốt hơn để cố gắng tìm ra lý do tại sao bạn có thứ gì đó ghi vào mảng của mình cùng một lúc.

0

Trong trường hợp của tôi, Swift 4 thực sự phát hiện ra một loại lỗi mà tôi sẽ không nhận thấy cho đến khi tôi bắt đầu gọi một hàm từ nhiều nơi. Chức năng của tôi đã được thông qua một mảng toàn cầu inout và nó đã tham chiếu cả tham số đó và tên chung. Khi tôi thay đổi hàm chỉ tham chiếu tham số, lỗi "truy cập đồng thời" đã biến mất.

0

Swift 4: Nếu bạn kiểm tra ngữ cảnh của mình trong phương thức observValue, chỉ cần biến biến ngữ cảnh của bạn thành tĩnh. Điều này blog post mô tả chi tiết vấn đề này.

1

Trong Cài đặt xây dựng của mục tiêu. Chọn No Enforcement cho Exclusive Access to Memory từ Swift Compiler - Code Generation

Các vấn đề liên quan