Gizmodo
Gizmodo

Reputation: 3202

Swift UnsafeMutableRawPointer Error

With Swift 3, I got this, without any errors:

private var SessionRunningContext = 0

func addObservers() {
   self.session.addObserver(self, forKeyPath: "running", options: .new, context: &SessionRunningContext)
}

func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
   let newValue: AnyObject? = change![NSKeyValueChangeKey.newKey] as AnyObject?
   switch context! {
     case &SessionRunningContext:
         // Do something
   }
}

However, when I build this on iOS 12, Xcode Beta, I get an error saying:

Use of extraneous '&'

for this line:

case &SessionRunningContext:

Upvotes: 3

Views: 503

Answers (1)

Martin R
Martin R

Reputation: 540065

That seems to be a bug in the Swift that comes with Xcode 10 beta 3, It has been fixed in Xcode 10.0 beta 4 (10L213o).

Possible workarounds for Xcode 10 beta 3 are:

A pattern with a where-clause (attribution goes to @Hamish for this one):

switch context {
    case let x where x == &SessionRunningContext:
    // Do something

}

An optional pattern:

switch context {
    case .some(&SessionRunningContext):
    // Do something

}

A simple if-statement:

if context == &SessionRunningContext {
     // Do something

}

Note also that only the address of a global variable or static property provides a persistent pointer suitable as context pointer, not that of an instance property, compare “Safety with Pointer Argument Conversions” in Interacting with C Pointers:

The pointer that results from these conversions is only guaranteed to be valid for the duration of a call. Even if you pass the same variable, array, or string as multiple pointer arguments, you could receive a different pointer each time. An exception to this is global or static stored variables. You can safely use the address of a global variable as a persistent unique pointer value, e.g.: as a KVO context parameter.

Upvotes: 4

Related Questions