2016-08-23 14 views
1

CloudKitからレコードを取得する関数を作成したい、一時的なネットワークエラーが発生した場合、関数は再試行する必要がある。Swiftネストされた関数とクロージャ変数

ここでの出会いにそれがネストされた関数internalWorkを(呼び出すことによって再試行エラーを取得した場合、私は、そのような機能(簡易)を定義
func fetchRecord(withRecordID recordID: CKRecordID, returnBlock: (optError: ErrorType?) -> Void){ 

    func internalReturnBlock(optError optError: ErrorType?){ 
     if NSThread.isMainThread() { 
      returnBlock(optError: optError) 
     } 
     else{ 
      dispatch_async(dispatch_get_main_queue(), { 
       returnBlock(optError: optError) 
      }) 
     } 
    } 

    func internalWork(){ 
     privateDB.fetchRecordWithID(recordID) { (optRecord, optError) in 
      if let error = optError{ 
       // IF NETWORK ERROR RETRY 
       internalWork() 
      } 
      else{ 
       internalReturnBlock(optError: nil) 
      } 
     } 
    } 

    internalWork() 
} 

私の質問は、ネストされた関数を使用するか、または作成の違いがどうなるかでありますローカルクロージャ変数? 例えば、ここで私は、クロージャ変数にinternalReturnBlockを変更します。

func fetchRecord2(withRecordID recordID: CKRecordID, returnBlock: (optError: ErrorType?) -> Void){ 

    var internalReturnBlock = { (optError: NSError?) in 
     if NSThread.isMainThread() { 
      returnBlock(optError: optError) 
     } 
     else{ 
      dispatch_async(dispatch_get_main_queue(), { 
       returnBlock(optError: optError) 
      }) 
     } 
    } 

    func internalWork(){ 
     privateDB.fetchRecordWithID(recordID) { (optRecord, optError) in 
      if let error = optError{ 
       // IF NETWORK ERROR RETRY 
       internalWork() 
      } 
      else{ 
       internalReturnBlock(nil) 
      } 
     } 
    } 


    internalWork() 
} 

可変ブロック対ネストされた関数を使用しての違いは何ですか? 利点や問題はありますか?

答えて

4

効果に違いはありません。 1つは名前付きの宣言された関数であり、もう1つは匿名です。しかし、それは両方の機能です。また、関数はSwiftのクロージャであるため、両方ともクロージャです。

匿名関数は、値を返す1つのライナーでreturnを省略するなど、いくつかの略語を使用することができます。しかし、それらの略語のどれも、究極的な効果的な違いはありません。

しかし、Swiftの無名関数には、宣言された関数にはないキャプチャリストという機能があります。これは保持サイクルを避けるのに役立ちます。

f { 
    [unowned self] in 
    return self.name 
} 

また、匿名関数は、それがその宣言に表示される用語を使用することができますので、それをパラメータとして取る関数の宣言の後に定義されています

f(param:String) { 
    return param 
} 

しかし、あなたがいない場合これらの機能を使用すると、どちらを使用するかは関係ありません。彼らは同じように動作します。

+2

私の本を読んで参考になるかもしれません。http://www.apeth.com/swiftBook/ch02.html#_anonymous_functions宣言された関数から匿名関数に切り替えるという私の動機は、基本的に名前が不要であることに注意してください。 – matt

+0

詳細な回答ありがとうございました!私は、closure変数が少なくとも宣言する方法ではclosure変数を呼び出すことができないことも知ったので、internalWork()はネストされた関数として残る必要があります。 –

+0

良い点!その限界を回避する方法があります。しかし、私はあなたの再帰がとても良いアイデアであるとは確信していません。私たちが決して通過できない場合はどうですか?最終的に実際のスタックオーバーフローが発生します。 – matt

関連する問題