Delegate는 왜 속성에서 웹을 지정해야 합니까?
개시하다
만약strong,weak 등 모든 속성을 적당히 더하면
기억 유출이 발생하면 선배에게 자주 구설에 오르나요?
어떻게 된 건지 정리 좀 했어요.
흔히 말하는 상황은:
Outlet, Delegate, Closures 등인가요?
SwiftLight에서도 경고가 표시됩니다.
이번에는 Delegate를 예로 들어 설명하겠습니다.
샘플 설명
1st화면, 2nd화면, 3rd화면을 구성하는 3개의 화면.
1st 화면 사양
버튼을 누르면 두 번째 화면으로 이동합니다.
FirstViewController.swiftimport UIKit
final class FirstViewController: UIViewController {
@IBAction func didTap2ndScene(_ sender: UIButton) {
let secondVC = UIStoryboard.viewController(storyboardName: "Main",
identifier: "SecondViewController")
self.navigationController?.pushViewController(secondVC!, animated: true)
}
}
2nd 화면 규격
속성을 사용하여 제3화면을 관리하는 실례.
2nd 화면에서 3d 화면까지의 Delegate 속성은 자신을 설정합니다.
버튼을 누르면 세 번째 화면으로 이동합니다.
SecondViewController.swiftimport UIKit
final class SecondViewController: UIViewController {
var thirdVC: ThirdViewController?
@IBAction func didTap3rdScene(_ sender: UIButton) {
thirdVC = UIStoryboard.viewController(storyboardName: "Main",
identifier: "ThirdViewController")
if let vc = thirdVC {
vc.delegate = self
self.navigationController?.pushViewController(vc, animated: true)
}
}
}
extension SecondViewController: ThirdDelegate {
func completion() {
print(#function)
}
}
3rd 화면 사양
delegate를 속성으로 관리합니다.모든 속성을 생략하여 strong으로 만듭니다.
버튼을 누르면delegate를 통해 2nd 화면에 알리고 화면을 닫습니다.
ThirdViewController.swiftimport UIKit
protocol ThirdDelegate: class {
func completion()
}
final class ThirdViewController: UIViewController {
var delegate: ThirdDelegate?
@IBAction func didTapGoBack(_ sender: UIButton) {
delegate?.completion()
self.navigationController?.popViewController(animated: true)
}
}
그렇다면 메모리 유출은 언제 일어날까?
정답은 두 번째 화면을 닫을 때 메모리 유출을 일으킨다는 것이다.
이유는 2nd 화면이strong에서 세 번째 화면의 실례를 유지하고 있기 때문이다.
또한 세 번째 화면에서delegate는strong에서 유지된다.
즉, 이것은 순환 인용으로 상호 인용 대상의 상태에 있다.
이를 통해 인스트루먼트의 Leak Checks에서 모니터링을 해도 메모리 유출이 감지된다.
그럼 어떡하지?
3rd 화면에서 관리되는delegate의 모든 속성을 weak로 설정합니다.
또는 제2화면에서 관리하는 제3화면의 실례를 weak로 설정합니다.
이렇게 하면 순환 인용을 방지할 수 있다.
ThirdViewController.swiftimport UIKit
protocol ThirdDelegate: class {
func completion()
}
final class ThirdViewController: UIViewController {
weak var delegate: ThirdDelegate?
@IBAction func didTapGoBack(_ sender: UIButton) {
delegate?.completion()
self.navigationController?.popViewController(animated: true)
}
}
인스트루먼트의 렉 체크에서 모니터링을 해도 메모리 유출은 발생하지 않는 것으로 확인됐다.
총결산
ARC를 잘 모르시는 분들.
Instruments의 Leak Checks로 모니터링을 해보면 곧 공부가 될 거야.
Closures의 생각도 마찬가지입니다.
클래스에서 클론 사용자를 참조하고 클론에서 클래스의 속성을 참조하기 때문입니다.
순환 인용이 발생하여 메모리 유출을 일으키다.
하지만 가능하면 변수의 범위를 좁히고 로컬 변수로 관리하면
메모리 유출을 막을 수 있을 것 같습니다.
Reference
이 문제에 관하여(Delegate는 왜 속성에서 웹을 지정해야 합니까?), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/eKushida/items/d526b0c6d0e3221e77e0
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import UIKit
final class FirstViewController: UIViewController {
@IBAction func didTap2ndScene(_ sender: UIButton) {
let secondVC = UIStoryboard.viewController(storyboardName: "Main",
identifier: "SecondViewController")
self.navigationController?.pushViewController(secondVC!, animated: true)
}
}
import UIKit
final class SecondViewController: UIViewController {
var thirdVC: ThirdViewController?
@IBAction func didTap3rdScene(_ sender: UIButton) {
thirdVC = UIStoryboard.viewController(storyboardName: "Main",
identifier: "ThirdViewController")
if let vc = thirdVC {
vc.delegate = self
self.navigationController?.pushViewController(vc, animated: true)
}
}
}
extension SecondViewController: ThirdDelegate {
func completion() {
print(#function)
}
}
import UIKit
protocol ThirdDelegate: class {
func completion()
}
final class ThirdViewController: UIViewController {
var delegate: ThirdDelegate?
@IBAction func didTapGoBack(_ sender: UIButton) {
delegate?.completion()
self.navigationController?.popViewController(animated: true)
}
}
import UIKit
protocol ThirdDelegate: class {
func completion()
}
final class ThirdViewController: UIViewController {
weak var delegate: ThirdDelegate?
@IBAction func didTapGoBack(_ sender: UIButton) {
delegate?.completion()
self.navigationController?.popViewController(animated: true)
}
}
ARC를 잘 모르시는 분들.
Instruments의 Leak Checks로 모니터링을 해보면 곧 공부가 될 거야.
Closures의 생각도 마찬가지입니다.
클래스에서 클론 사용자를 참조하고 클론에서 클래스의 속성을 참조하기 때문입니다.
순환 인용이 발생하여 메모리 유출을 일으키다.
하지만 가능하면 변수의 범위를 좁히고 로컬 변수로 관리하면
메모리 유출을 막을 수 있을 것 같습니다.
Reference
이 문제에 관하여(Delegate는 왜 속성에서 웹을 지정해야 합니까?), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/eKushida/items/d526b0c6d0e3221e77e0텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)