1

機能を同期しようとすると、多くの投稿が通知に対してアドバイスするようですが、誤ってオブジェクトを保持してメモリの問題を引き起こす可能性があるため、閉鎖コールバックに注意する他の投稿もあります。通知とネットワークコールのコールバッククロージャを選択する際のメモリについての懸念はありますか?

fooのカスタムビューコントローラの内部に、Barクラスを使用してサーバーからデータを取得するものとします。

class CustomViewController : UIViewController { 

    function foo() { 
     // Do other stuff 
     // Use Bar to get data from server 
     Bar.getServerData() 
    } 

} 

オプション1:コールバックを受け入れるようにgetServerDataを定義します。 CustomViewControllerの中にクロージャとしてコールバックを定義します。

オプション2:コールバックの代わりにNSNotificationsを使用してください。 getServerDataの中に、サーバーがデータを返すときにNSNotificationを転記し、通知のためにCustomViewControllerが登録されていることを確認します。

オプション1は、NSNotification(コンパイラチェック、トレーサビリティなど)に注意しているが、コールバックを使用しないと、CustomViewControllerが不必要に保持され、メモリの問題が発生する可能性があるという潜在的な問題を引き起こします。

もしそうなら、コールバックを使用してリスクを軽減する正しい方法はありますが、クロージャを使用することはありませんか?言い換えれば、getServerDataコールバックと一致するシグニチャを持つCustomViewControllerの中に関数を定義し、この関数へのポインタをgetServerDataに渡しますか?

+0

IMHOはどちらも有効なアプローチです。オプション1ははるかに簡潔で分かりやすく、簡単に正しいです。したがって、オプション1が好ましい。しかし、あなたはいくつかの他の答えによって間違っているように思えます。メモリ管理と同期は直交する概念であり、独自の問題の根源を持っています。 – CouchDeveloper

答えて

0

私はいつもと一緒です。オプション1[weak self]を使用するか、メモリの問題を避けるために必要なものを覚えておく必要があります。

現実世界での例:

filterRepository.getFiltersForType(filterType) { [weak self] (categories) in 
    guard let strongSelf = self, categories = categories else { return } 
    strongSelf.dataSource   = categories 
    strongSelf.filteredDataSource = strongSelf.dataSource 
    strongSelf.tableView?.reloadData() 
} 

したがって、この例ではあなたは私が完了閉鎖へselfへの参照を渡すことがわかりますが、weak基準とすることができます。オブジェクトがまだ存在しているかどうかを確認しています。まだ解放されていない場合は、guardステートメントを使用し、weakの値をアンラップします。完成閉鎖とネットワーク呼び出しの

定義:

class func getFiltersForType(type: FilterType, callback: ([FilterCategory]?) ->()) { 
    connection.getFiltersCategories(type.id).response { (json, error) in 
     if let data = json { 
      callback(data.arrayValue.map { FilterCategory(attributes: $0) }) 
     } else { 
      callback(nil) 
     } 
    } 
} 
+2

「弱い自己」の必要性はしばしば誇張されます。保持サイクル、したがってメモリリークを生成するには、循環参照が必要です。あなたの例では、クロージャーは 'self'をキャプチャしますが、' FilterRepository'はクロージャーを強力なプロパティーに取り込まないので、 'getFiltersForType'がクロージャーを呼び出すと、クロージャーが解放されます。これは、クロージャが解放され、呼び出し元のオブジェクト( 'self')を保持しているクロージャが解放されていることを意味するので、すべてがきちんと整理されます – Paulw11

+0

@ Paulw11コメントありがとう、私は間違ってコードをコピーしました、' filterRepository'はプロパティです私のデータソースオブジェクトには 'weak'があります。 – Krodak

+0

' filterRepository'については関係ありません。 'getFiltersForType'で' self.closureProperty = callback'のようなことをすれば、リークの可能性があります。 – Paulw11

0

私は、その場合の閉鎖のために立っています。不必要な保持を避けるためには、クロージャが適切なcapture listを確実に定義する必要があります。

関連する問題