私はARCと弱/無所有の自己(Shall we always use [unowned self] inside closure in Swift)についてのstackoverflowとappleのドキュメントに関する研究を行ってきました。私は、強いリファレンスサイクルと、メモリリークの原因となるものではないことについての基本的な考え方を得ています。しかし、私はクロージャーでWeak/Unownedの自己を使用するときに頭を抱えようとしています。むしろ "理論"に入るのではなく、私が持っている底の3つの事例に関して親切に説明することができれば、本当に助けになると思います。私の質問は閉鎖と結果の弱い例
である、しかし(私が?。私はUIViewのは、自己に関連付けられていないことをどこかで見たので、ケース2のために必要がないと考え、それらのすべてに弱い自己を入れて、それはOK、私が何を置く場合です私の頭痛の原因になるものはありますか?
答えが「いいえ」なら、私は3つの場合すべてどこに弱い自己を置くこともできません。 ..たとえば、このVCのときにプログラムがクラッシュします....
これは私がweakSelfを使用する方法です 閉鎖の外側で、私は弱いvarを入れたweakSelf =自己 それから閉鎖のすべての自己をweakSelfで置き換えますか? いいですか?私のコードの大部分
--Update--
Case 1:
FIRAuth.auth()?.signInWithCredential(credential, completion: { (user: FIRUser?, error: NSError?) in
self.activityIndicatorEnd()
self.performSegueWithIdentifier(SEGUE_DISCOVER_VC, sender: self)
})
Case 2:
UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.1, animations: {
self.messageLbl.alpha = 0.5
})
Case 3:
//checkUserLoggedIn sends a request to firebase and waits for a response to see if the user is still authorised
checkUserLoggedIn { (success) in
if success == false {
// We should go back to login VC automatically
} else {
self.discoverTableView.delegate = self
self.discoverTableView.dataSource = self
// Create dropdown menu
let menuView = BTNavigationDropdownMenu(navigationController: self.navigationController, title: self.dropDownItems.first!, items: self.dropDownItems)
menuView.didSelectItemAtIndexHandler = {[weak self] (indexPath: Int) ->() in
if indexPath == 0 {
self?.mode = .Closest
self?.sortByDistance()
} else if indexPath == 1 {
self?.mode = .Popular
self?.sortByPopularity()
} else if indexPath == 2 {
self?.mode = .MyPosts
self?.loadMyPosts()
} else {
print("Shouldnt get here saoihasiof")
}
}
// Xib
let nib = UINib(nibName: "TableSectionHeader", bundle: nil)
self.xibRef = nib.instantiateWithOwner(self, options: nil)[0] as? TableSectionHeader
self.discoverTableView.registerNib(nib, forHeaderFooterViewReuseIdentifier: "TableSectionHeader")
// Set location Manager data
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
// Check location service status
if self.locationAuthStatus == CLAuthorizationStatus.AuthorizedWhenInUse {
// Already authorised
self.displayMessage.hidden = false
} else if self.locationAuthStatus == CLAuthorizationStatus.NotDetermined {
// Have not asked for location service before
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("LocationVC") as! LocationVC
vc.locationVCDelegate = self
self.presentViewController(vc, animated: true, completion: nil)
} else {
let alertController = UIAlertController(title: "Enable Location", message: "location is required to load nearby posts", preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Default, handler: nil)
let settingsAction = UIAlertAction(title: "Settings", style: .Default, handler: { (action: UIAlertAction) in
let settingsUrl = NSURL(string: UIApplicationOpenSettingsURLString)
if let url = settingsUrl {
UIApplication.sharedApplication().openURL(url)
}
})
alertController.addAction(settingsAction)
alertController.addAction(cancelAction)
self.presentViewController(alertController, animated: true, completion: nil)
self.displayMessage.hidden = false
self.displayMessage.text = "Could not determine your location to find nearby posts. Please enable location Service from settings"
}
// Styling
self.refreshBtn.tintColor = COLOR_NAVIGATION_BUTTONS
self.discoverTableView.backgroundColor = COLOR_DISCOVERVC_TABLEVIEW_BACKGROUND
// Allow navigation bar to hide when scrolling down
self.hidingNavBarManager = HidingNavigationBarManager(viewController: self, scrollView: self.discoverTableView)
// Allow location to start updating as soon as we have permission
self.locationManager.startUpdatingLocation()
}
}
はすべてが、アクションのいずれかが行われる前に、インターネット接続があるかどうかを確認いずれかであることクロージャ内にラップされたケース3のように見えます。だから私はどこにでも弱い自己を持っているかもしれない? 4. 私はこの閉鎖は弱い/所有されていない自己を持っていないにもかかわらず、それは強い参照を作成することはありませんと言うことは修正頂く場合(およびメモリに関する
--update 2--
Case 4:
// The haveInternetConnectivity function checks to see if we can reach google within 20 seconds and return true if we can
haveInternetConnectivity { (success) in
if success == false {
self.dismissViewControllerAnimated()
} else {
self.label.text = "You are logged in"
self.performSegueWithIdentifier("GoToNextVC")
}
}
質問リーク)は、完了ブロックが実行される前にVCが破棄されても、インターネット状態を確認したときにXcodeがコンプリートブロック内でコードを実行しようとし、自己がもう存在しないため何もしません(クラッシュしません)。コードがクロージャの最後の行に到達すると、自己への強い参照が破壊され、VCの割り当てが解除されます。
ので
が いずれかの方法だけで(試してみて、それを実行するために反対し、何も起こらないよう)Xcodeのがより良い練習が、私の手には何の問題を意味しているものの行を無視することを意味し、その場合には、[弱いセルフ]を入れて
あなたは「役に立たない」という意味を詳しく教えてください。また、インターネットのリクエストから待っている何らかの閉鎖が、常に弱い、あるいは所有されていない自分を必要としていると言うのは公正でしょうか?そして、それらの事実のほとんどすべてにおいて弱い自己であることは間違いないでしょうか? – user172902
'animation'クロージャの弱い参照はユーティリティを提供しません:' animateWithDuration'に供給される 'animation'クロージャは、後で実行される完了ハンドラではありません(別々の' completion'クロージャがありますが、すべて)。これは直ちに呼び出され、アニメーションが開始されますが、クロージャはアニメーションの期間中に「self」への強い参照を保持しません。 – Rob
ネットワーク閉鎖には常に弱い/無所属が必要です。いいえ、これは当てはまりません。たとえば、このクロージャーで何かを実行する必要があるかもしれません(たとえば、ネットワークリクエストの完了に関するローカルDBの更新、ダウンロードしたイメージのキャッシュへの保存など)。クロージャのコードがオブジェクトへの参照を保持する必要はありません(たとえばUIを更新するだけで、キャッシュやデータベース、モデル構造は更新しないなど)。無意識のうちに「弱い」を使用しないでください。クロージャの中身を見て、弱いかどうかを決定します。 – Rob