programing

약한 자아는 어디로 가는 거지?

kingscode 2023. 9. 18. 22:51
반응형

약한 자아는 어디로 가는 거지?

제가 자주 하는 일인데요.

let when = DispatchTime.now() + 2.0
DispatchQueue.main.asyncAfter(deadline: when) {
   beep()
}

그리고 한 앱에서 우리는 종종 이것을 합니다.

tickle.fresh(){
    msg in
    paint()
}

이렇게 하면.

let when = DispatchTime.now() + 2.0
DispatchQueue.main.asyncAfter(deadline: when) {
   tickle.fresh(){
      msg in
      paint()
   }
}

물론 당신은 이것을 해야 합니다.

let when = DispatchTime.now() + 2.0
DispatchQueue.main.asyncAfter(deadline: when) { [weak self] _ in
   tickle.fresh(){
      msg in
      self?.paint()
   }
}

아니면, 어쩌면 이것.

let when = DispatchTime.now() + 2.0
DispatchQueue.main.asyncAfter(deadline: when) {
   tickle.fresh(){
      [weak self] msg in
      self?.paint()
   }
}

아니면 이거.

let when = DispatchTime.now() + 2.0
DispatchQueue.main.asyncAfter(deadline: when) { [weak self] _ in
   tickle.fresh(){
      [weak self] msg in
      self?.paint()
   }
}

어떻게 할까요?

세 가지 제안 모두 완벽하게 들어맞는 것 같습니다.여기서 의미의 깊이는 어느 정도입니까?그리고 어느 쪽이 해야 할까요?강한 참조는 약한 참조, 약한 참조 또는 강한 참조입니까?될 것인가 말 것인가?그것이 문제입니다!

, 으로 를 하는 에 할 가 과 가 할 으로 에 과 DispatchQueue.main.asyncAfter, 폐쇄가 어느 시점에서 실행될 것이기 때문입니다.그러므로 당신이 약하게 잡든 말든self인 유지 사이클, 인 을 는 입니다 입니다 인 는 을 ,tickle.fresh(또한 그렇지 않습니다.).

이 A 를 이 를 [weak self]쪽처록록처nasyncAfter폐쇄는 전적으로 당신이 원하는지 아닌지에 달려있습니다.self폐쇄가 호출될 때까지 유지됩니다(설정한 시간 이후).self.[weak self]만약 그렇다면, 넣지 마세요.

이 A 를 이 를 [weak self]내부의 폐쇄(에게 전달된 것)에tickle.fresh는 이미 달라집니다.) 했는지 에 에 했는지 self바깥쪽 폐쇄에만약 그렇지 않다면, 당신은 그 때릴 수 있습니다.[weak self]내부 폐쇄가 유지되는 것을 방지하기 위해.가 이미 포착된 부가게우된미우f된self, 그러면 내부 폐쇄는 이미 다음에 대한 약한 참조를 가질 입니다.self, 이렇게 덧붙여서[weak self]내부 폐쇄는 영향을 주지 않습니다.

요약하자면 다음과 같습니다.


DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
   tickle.fresh { msg in
      self.paint()
   }
}

self외부 및 내부 클로저에 의해 유지됩니다.


DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
   tickle.fresh { msg in
      self?.paint()
   }
}

self어느 쪽의 폐쇄도 유지되지 않습니다.


DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
   tickle.fresh { [weak self] msg in
      self?.paint()
   }
}

인 와 하게 인 인 하게 [weak self]내부 폐쇄가 영향을 미치지 않기 때문에, 다음과 같이self외부 폐쇄에 의해 이미 약하게 포착된 상태입니다.


DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
   tickle.fresh { [weak self] msg in
      self?.paint()
   }
}

self외부 클로저는 유지되지만 내부 클로저는 유지되지 않습니다.


, 이, , 를 원하지 않을 도 있습니다.self외부 폐쇄에 의해 유지되지만 내부 폐쇄에 의해 유지되기를 원합니다.이 경우 외부 폐쇄에서 로컬 변수를 선언하여 다음을 강력하게 참조할 수 있습니다.self 클로저에서 할 수 , 에서 할 에서 할

DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
   guard let strongSelf = self else { return }
   tickle.fresh { msg in
      strongSelf.paint()
   }
}

지금이다,self외부 폐쇄에 의해 생명을 유지할 수는 없겠지만, 일단 이름이 지어지면,self여전히 존재합니다. 폐쇄가 해제될 때까지 내부 폐쇄에 의해 유지됩니다.


대응:

강한 참조는 약한 참조, 약한 참조 또는 강한 참조입니까?

약한 참조는 값 유형인 옵션으로 구현됩니다.따라서 하나에 대한 강력한 참조를 직접적으로 가질 수는 없습니다. 대신 먼저 하나의 랩을 풀고 기본 인스턴스에 대한 강력한 참조를 수행해야 합니다.이 경우에는 단순히 강력한 참조(위의 예와 정확히 일치함)를 다루고 있습니다.strongSelf).

그러나 약한 참조가 박스화된 경우(닫힘 캡처에서 이런 현상이 발생 – 값 유형이 힙 할당 상자에 포함됨), 실제로 해당 박스에 대한 강력한 참조를 가질 수 있습니다.이 결과는 원래 인스턴스에 대한 약한 참조에 해당합니다. 보이지 않는 추가 방향이 있을 뿐입니다.

사실, 이것은 바로 외부 폐쇄가 약하게 포착되는 예제에서 일어나는 일입니다.self그리고 내부의 폐쇄는 약한 참조를 포착합니다.으로 두 모두 Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ self.

언급URL : https://stackoverflow.com/questions/41991467/where-does-the-weak-self-go

반응형