2016-06-27 8 views
11

SwiftのDEVELOPMENT-SNAPSHOT-2016-06-06-aバージョンを使用しています。簡単な例であるここでは、SwiftのDispatch Closure内での構造体インスタンス変数の変更

Closure cannot implicitly capture a mutating self parameter

良く説明するために:

public struct ExampleStruct { 
    let connectQueue = dispatch_queue_create("connectQueue", nil) 
    var test = 10 

    mutating func example() { 
    if let connectQueue = self.connectQueue { 
     dispatch_sync(connectQueue) { 
     self.test = 20 // error happens here 
     } 
    } 
    } 
} 
私は様々な場所で @noescapeを使用してみましたが、私はまだ、次のエラーを持って、この問題を回避するように見えることはできません

これらのSwiftバイナリで何かが変更されている必要があります。これにより、以前は動作していたコードが壊れてしまいました。私が避けたい回避策は、私の構造体をクラスにすることで、問題を解決するのに役立ちます。別の方法があれば教えてください。

+0

新しいディスパッチAPIはそうあなたが明示的にキャプチャを必要としないsync方法@noreturnを作りますか? –

+0

@MartinR MacでXcode 7.3.1を使用しています – tfrank377

答えて

11

私はそのエラーでビルドを使用していないので、私は、それをテストすることはできませんが、私は自己を捕捉することによって、かなり確信しています明示的あなたはそれを修正することができます:

dispatch_sync(connectQueue) { [self] in 
    self.test = 20 
} 

編集:どうやら、それは動作しません、多分あなたは(TBHとても素敵ではない)、これを試すことができます。

var copy = self 
dispatch_sync(connectQueue) { 
    copy.test = 20 
} 
self = copy 

をあなたWA場合理由をもっと詳しく知るには、here is the responsible Swift proposal。マックOS(?Xcodeのバージョン)上またはLinux上

connectQueue.sync { 
    test = 20 
} 
+0

にも影響を受けていることがわかります。「まだ弱い」、「所有されていない」、またはキャプチャリストに指定されていないと予想されます。私は新しいAPIの使用を楽しみにしていますが、現在の実装では解決策がないと思いますか? – tfrank377

+0

@ tfrank377私は私の答えを編集しました – Kametrixom

+0

うん、それはうまくいきますが、あなたが言ったように、あまり良くありません。私はよりクリーンなコードを持つために構造体の代わりにクラスを使用すると思います。つまり、これは疑問に答えるもので、06/06スイフトのスナップショットで見られる最良の解決策です。 – tfrank377

1

最近dev snapshotSwiftと記載されているので、Swift3を使用しています。以下試してみて、それが動作するかどうか私に教えて:

public struct ExampleStruct { 
    let connectQueue = DispatchQueue(label: "connectQueue", attributes: .concurrent)//This creates a concurrent Queue 

    var test = 10 

    mutating func example() { 
     connectQueue.sync { 
      self.test = 20 
     } 
    } 
} 

あなたはキューの他のタイプに興味がある場合は、これらの点を確認してください。

let serialQueue = DispatchQueue(label: "YOUR_QUEUE", attributes: .serial) 
serialQueue.sync { 
    // 
} 

mainQueue非同期および同期取得:

DispatchQueue.main.async { 
    //async operations 
} 
DispatchQueue.main.sync { 
    //sync operations 
} 

あなたが背景に興味があれば:

DispatchQueue.global(attributes: .qosDefault).async { 
    //async operations 
} 

あなたはSwift3の新機能のために、既存のバージョンへの変更のためにこれを参照することができる:Migrating to Swift 2.3 or Swift 3 from Swift 2.2

+0

私はこの特別なスウィフト3スナップショットを信じていますが、 'DispatchQueue'クラスは存在しません。私はそれを使用しようとすると "未解決の識別子"エラーが表示されます。 – tfrank377

+0

あなたの答えはhttps://stackoverflow.com/a/37806522/1033581 –

関連する問題