2016-09-26 11 views
9

W swift 2.2, moglibyśmy zmutować strukturę lub enum w zamknięciu, gdy był on wewnątrz funkcji mutowania. Ale w szybkim 3.0 nie jest już możliwe. I pojawia się następujący błądMutujące self (struct/enum) wewnątrz uciekającego zamknięcia w Swift 3.0

zamknięcie nie może w sposób dorozumiany zdobył mutowania parametr SELF

Oto fragment kodu,

struct Point { 
    var x = 0.0, y = 0.0 

    mutating func moveBy(x deltaX: Double, y deltaY: Double) { 
     x += deltaX 
     y += deltaY 

     test { (a) -> Void in 
      // Get the Error in the below line. 
      self.x = Double(a) 
     } 

    } 

    mutating func test(myClosure: @escaping (_ a: Double) -> Void) { 
     myClosure(3) 
    } 
} 

I Get That typy wartości nie mają być zmienny. Mam przypadki, w których muszę zmodyfikować jedną zmienną w strukturze w ramach jednej z funkcji, gdy otrzymam odpowiedź API. (W zamknięciu zamknięcia)

Czy to, co robiłem w szybkim 2.2, jest niemożliwe, czy jest na to sposób?

+1

Usuń '@ escaping' ... dlaczego go masz? –

+1

@MartinR jest ucieczką, ponieważ zamknięcie zakończenia Alamofire. – akshaynhegde

+0

To prawdopodobnie wyjaśnia to: https://github.com/apple/swift-evolution/blob/master/proposals/0035-limit-inout-capture.md. –

Odpowiedz

1

Tak, możesz zrobić coś takiego.

struct Point { 

    var x = 0.0, y = 0.0 

    mutating func moveBy(x deltaX: Double, y deltaY: Double) { 
     x += deltaX 
     y += deltaY 

     test { (a) -> Void in 

      self.x = Double(a) 
     } 
    } 

    mutating func test(myClosure: (_ a: Double) -> Void) { 
     myClosure(3) 
    } 
} 
6

Problemem jest to, że zamknięcia @escaping mogą być przechowywane w celu późniejszego wykonania:

Escaping Closures

Zamknięcie mówi się uciec funkcji, kiedy zamknięcie jest przekazywane jako argument do funkcji, ale jest wywoływana po powrocie funkcji. ...

Jednym ze sposobów, że zamknięcie może uciec jest przechowywane w zmiennej, która jest zdefiniowana poza funkcją ....

Ponieważ zamknięcie mogą być przechowywane i żyć poza zakresem funkcja, struct/enum wewnątrz zamknięcia (self) zostanie skopiowane (jest to wartość) jako parametr zamknięcia. A jeśli pozwolono na mutację, zamknięcie mogło mieć starą kopię, powodując niepożądane skutki.

Więc, w odpowiedzi na twoje pytanie, nie możesz; chyba że jesteś w stanie usunąć "@escaping" (nie twoja sprawa, ponieważ jest to API innej firmy)

1

Struct to typ wartości. Tak więc, gdy używasz jako Model lub ModelView, możesz stworzyć zamknięcie z nową wartością do VC.

struct Point { 
    var x = 0.0, y = 0.0 

    mutating func moveBy(x deltaX: Double, y deltaY: Double) { 
     x += deltaX 
     y += deltaY 

     test { [x, y](a) -> Point in 
      // Get the Error in the below line. 
      return Point(x: Double(a), y: y) 
     } 

    } 

    mutating func test(myClosure: @escaping (_ a: Double) -> Point) { 
     self = myClosure(3) 
    } 
} 
Powiązane problemy