Simultaneous accesses to 0x1c0a7f0f8, but modification requires exclusive access error on Xcode 9 beta 4

后端 未结 11 1823
孤城傲影
孤城傲影 2020-11-29 05:15

my project uses both Objective-C and Swift code. When a user logs in, it calls a set of apis for user preference, I have a DataCoordinator.swift class which schedules the AP

相关标签:
11条回答
  • 2020-11-29 05:45

    The answers by @Mark Bridges and @geek1706 are good answers but I would like to add my 2 cents about this matter and give a general example.

    As stated above this is a feature in Swift 4 SE-176.

    The implementation should still be permitted to detect concurrent conflicting accesses, of course. Some programmers may wish to use an opt-in thread-safe enforcement mechanism instead, at least in some build configurations.

    The exclusive access enforces that every write mutation of vars must be exclusive when accessing that variable. In a multithread environment, multiple threads accessing a shared var and one or more can modify it.

    There's nothing like a good example: If we try to mutate a shared value in a multi-threaded environment using an abstraction (mutation occurs on a protocol type) between 2 objects and the Exclusive Access to Memory is on, our app will crash.

    protocol Abstraction {
      var sharedProperty: String {get set}
    }
    
    class MyClass: Abstraction {
      var sharedProperty: String
    
      init(sharedProperty: String) {
         self.sharedProperty = sharedProperty
      }
    
      func myMutatingFunc() {
         // Invoking this method from a background thread
         sharedProperty = "I've been changed"
      }
    }
    
    
    class MainClass {
       let myClass: Abstraction
    
       init(myClass: Abstraction) {
         self.myClass = myClass
       }
    
       func foobar() {
          DispatchQueue.global(qos: .background).async {
             self.myClass.myMutatingFunc()
          }
       }
    }
    
    let myClass = MyClass(sharedProperty: "Hello")
    let mainClass = MainClass(myClass: myClass)
    // This will crash
    mainClass.foobar()
    

    Since we didn't state that the Abstraction protocol is class bound, during runtime, inside myMutatingFunc, the capture of self will be treated as struct even though we injected an actual class (MyClass).

    Escaping variables generally require dynamic enforcement instead of static enforcement. This is because Swift cannot reason about when an escaping closure will be called and thus when the variable will be accessed.

    The solution is to bound the Abstraction protocol to class:

    protocol Abstraction: class
    
    0 讨论(0)
  • 2020-11-29 05:48

    Only in Swift 4 and when using .initial option for your KVO Settings

    If you check your context in observeValue method, just make your context variable static. This blog post describes this bug in detail.

    0 讨论(0)
  • 2020-11-29 05:52

    What I would do is change FetchOperation to a class instead of struct.

    0 讨论(0)
  • 2020-11-29 05:52

    Swift 5 here. I was calling a function from a property didSet and testing another property from the same object and I got this error.

    I fixed it by calling my function from within another thread:

    DispatchQueue.global(qos: .userInitiated).async {
        // do something
    }
    

    Basic fix but it works.

    0 讨论(0)
  • 2020-11-29 05:53

    Returning zero in the numberOfSections override function will cause this crash:

    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        // This causes a crash!    
        return 0
    }
    

    Simple solution - return 1 in the function above and then return 0 in the collectionView(_:numberOfItemsInSection:) function.

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    
    0 讨论(0)
提交回复
热议问题