ARC 및 약점/비 소유 자체 (Shall we always use [unowned self] inside closure in Swift)에 대한 stackoverflow 및 사과 설명서에 대한 조사를 수행했습니다. 나는 강력한 참조주기와 메모리 누출을 일으키는 좋은 방법에 대한 기본 아이디어를 얻는다. 그러나 나는 클로저에서 Weak/Unowned self를 사용할 때 주위를 두려워하고있다. 오히려 "이론"에 들어가기 전에, 나는 누군가가 내가 가진 밑의 3 가지 경우에 대해 친절하게 설명 할 수 있다면 정말 도움이 될 것이라고 생각한다. 내 질문은 약한 자기 폐쇄 및 결과 예제
- 이 확인 그들 (내가 무엇을 넣으면, 내가있는 UIView 그러나? 자기와 연관되지 않은 어딘가에 보았 기 때문에 필요가없는 경우 두 가지에 대한 생각의 모든 약한 자기를 넣어하는 것입니다 약한 자아가 있다면 두통을 일으킬 수있는 것이 무엇입니까?
대답이 '아니오'라고 대답하면 세 가지 경우 모두 약한 자기를 넣을 수 없습니다. 예를 들어 대답하면 크게 좋아할 것입니다. .. 예를 들어,이 VC 때 .... 프로그램이 충돌합니다.
이것은 weakSelf를 사용하려고하는 방법입니다. 클로저 외부에서 약한 var weakSelf = self를 입력했습니다. 그런 다음 closure의 모든 자체를 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는 인터넷 상태를 확인할 때 완료 블록 내에서 코드를 실행하려고 시도하기 때문에 자체가 더 이상 존재하지 않으므로 아무 것도하지 않습니다 (크래시 없음). 그리고 일단 코드가 클로저 안의 마지막 라인에 도달하면, self에 대한 강한 참조가 파괴되어 VC가 할당 해제됩니까?
그래서 단지 (그것을 시도하고 실행하는 데 반대하고 아무 일도 발생하지 않기 때문에) 더 연습하지만 하나 내 손에 아무런 문제 방법
을 의미하는 그 라인을 무시하는 것이라고 엑스 코드를 의미하는 경우 [약한 자기를] 퍼팅
"유틸리티를 제공하지 않음"이란 의미를 상세히 설명해 주시겠습니까? 또한 인터넷 요청에서 대기하는 모든 종결과 관련된 폐쇄는 항상 약하거나 소유되지 않은 자기가 필요하다고 말하는 것이 합리적입니까? 그리고 거의 모든 경우에 약한 자아가된다는 것이 맞습니까? – user172902
'animation' 클로저의 weak 참조가 유틸리티를 제공하지 않음 :'animateWithDuration'에 제공된'animation' 클로저가 나중에 실행되는 완료 핸들러가 아닙니다 (별도의'completion' 클로저가 있지만 이것은 왁스의 별도 공입니다 전부). 즉각적으로 호출되고 애니메이션이 시작되지만 클로저는 애니메이션 기간 동안 'self'에 대한 강력한 참조를 유지하지 않습니다. – Rob
다시 네트워크 폐쇄는 항상 약점/미 소유가 필요합니다. 아니요, 그렇지 않습니다.예를 들어,이 클로저에서 실행해야 할 작업 (예 : 네트워크 요청 완료와 관련된 로컬 db 업데이트, 다운로드 한 이미지를 캐시에 저장하는 작업 등)을 수행 할 수 있습니다. 클로저에있는 코드가 객체에 대한 참조를 유지할 필요가 없으면 (예 : UI 만 업데이트하고 있지만 캐시 또는 데이터베이스 또는 모델 구조는 업데이트하지 않음) 약점을 사용하십시오. 어리석게도 약한 것을 사용하지 마십시오. 클로저에있는 것을보고 약해 지거나 그렇지 않아야하는지 결정하십시오. – Rob