Chúng ta sẽ luôn sử dụng [bản thân không có chủ đích] trong đóng cửa trong Swift


467

Trong WWDC 2014 phiên 403 Trung cấp Swiftbảng điểm , có slide sau

nhập mô tả hình ảnh ở đây

Người nói đã nói trong trường hợp đó, nếu chúng ta không sử dụng [unowned self]ở đó, nó sẽ bị rò rỉ bộ nhớ. Có nghĩa là chúng ta nên luôn luôn sử dụng [unowned self]bên trong đóng cửa?

Trên dòng 64 của ViewControll.swift của ứng dụng Swift Weather , tôi không sử dụng [unowned self]. Nhưng tôi cập nhật giao diện người dùng bằng cách sử dụng một số @IBOutlets self.temperatureself.loadingIndicator. Nó có thể ổn vì tất cả những @IBOutletgì tôi xác định là weak. Nhưng để an toàn, chúng ta có nên luôn luôn sử dụng [unowned self]?

class TempNotifier {
  var onChange: (Int) -> Void = {_ in }
  var currentTemp = 72
  init() {
    onChange = { [unowned self] temp in
      self.currentTemp = temp
    }
  }
}

liên kết hình ảnh bị hỏng
Daniel Gomez Rico

@ DanielG.R. Cảm ơn, tôi có thể nhìn thấy nó. i.stack.imgur.com/Jd9Co.png
Jake Lin

2
Trừ khi tôi nhầm, ví dụ đưa ra trong slide là không chính xác onChangenên là một [weak self]đóng cửa, vì đó là một thuộc tính công khai (bên trong, nhưng vẫn), do đó, một đối tượng khác có thể lấy và lưu trữ bao đóng, giữ đối tượng TempNotifier xung quanh (vô thời hạn nếu đối tượng sử dụng đã không buông bỏ việc onChangeđóng cửa cho đến khi nó thấy nó TempNotifierbiến mất, thông qua tham chiếu yếu của chính nó đối với TempNotifier) . Nếu var onChange …được private var onChange …thì [unowned self]sẽ đúng. Tôi không chắc chắn 100% về điều này mặc dù; Ai đó làm ơn sửa cho tôi nếu tôi sai.
Slipp D. Thompson

@Jake Lin `var onChange: (Int) -> Void = {}` các dấu ngoặc nhọn biểu thị một bao đóng trống? giống như trong việc xác định một mảng trống với []? Tôi không thể tìm thấy lời giải thích trong các tài liệu của Apple.
bibscy

@bibscy có, {}là bao đóng rỗng (ví dụ của bao đóng) là mặc định (không làm gì cả), (Int) -> Voidlà định nghĩa đóng.
Jake Lin

Câu trả lời:


871

Không, chắc chắn có những lúc bạn không muốn sử dụng [unowned self]. Đôi khi bạn muốn đóng cửa để tự chụp để đảm bảo rằng nó vẫn ở xung quanh thời điểm đóng cửa được gọi.

Ví dụ: Thực hiện một yêu cầu mạng không đồng bộ

Nếu bạn đang làm cho một yêu cầu mạng không đồng bộ bạn làm muốn đóng cửa để giữ selfcho khi kết thúc yêu cầu. Đối tượng đó có thể đã bị xử lý nhưng bạn vẫn muốn có thể xử lý yêu cầu hoàn thiện.

Khi nào nên sử dụng unowned selfhayweak self

Thời gian duy nhất mà bạn thực sự muốn sử dụng [unowned self]hoặc [weak self]là khi bạn sẽ tạo ra một chu trình tham chiếu mạnh mẽ . Một chu trình tham chiếu mạnh mẽ là khi có một vòng sở hữu nơi các đối tượng cuối cùng sở hữu lẫn nhau (có thể thông qua bên thứ ba) và do đó chúng sẽ không bao giờ bị xử lý vì cả hai đều đảm bảo rằng nhau dính vào nhau.

Trong trường hợp cụ thể của một bao đóng, bạn chỉ cần nhận ra rằng bất kỳ biến nào được tham chiếu bên trong nó, sẽ được "sở hữu" bởi bao đóng. Miễn là đóng cửa xung quanh, những đối tượng đó được đảm bảo xung quanh. Cách duy nhất để ngăn chặn quyền sở hữu đó, là làm [unowned self]hoặc [weak self]. Vì vậy, nếu một lớp sở hữu một bao đóng và bao đóng đó thu được một tham chiếu mạnh đến lớp đó, thì bạn có một chu trình tham chiếu mạnh giữa bao đóng và lớp. Điều này cũng bao gồm nếu lớp sở hữu một cái gì đó sở hữu đóng cửa.

Cụ thể trong ví dụ từ video

Trong ví dụ trên slide, TempNotifiersở hữu bao đóng thông qua onChangebiến thành viên. Nếu họ không tuyên bố selfunowned, việc đóng cửa cũng sẽ selftạo ra một chu kỳ tham chiếu mạnh mẽ.

Sự khác biệt giữa unownedweak

Sự khác biệt giữa unownedweakđược weaktuyên bố là Tùy chọn trong khi unownedkhông. Bằng cách khai báo, weakbạn có thể xử lý trường hợp có thể là con số không bên trong bao đóng tại một số điểm. Nếu bạn cố gắng truy cập vào một unownedbiến số không, nó sẽ làm hỏng toàn bộ chương trình. Vì vậy, chỉ sử dụng unownedkhi bạn tích cực, biến đó sẽ luôn tồn tại trong khi xung quanh đóng


1
Chào. Câu trả lời chính xác. Tôi đang đấu tranh để hiểu bản thân vô danh. Một lý do để sử dụng yếu đuối chỉ đơn giản là "bản thân trở thành một tùy chọn", là không đủ đối với tôi. Tại sao tôi đặc biệt muốn sử dụng ' stackoverflow

19
@robdashnash, Ưu điểm của việc sử dụng bản thân không có tên là bạn không phải mở khóa tùy chọn có thể là mã không cần thiết nếu bạn biết chắc chắn về thiết kế, rằng nó sẽ không bao giờ là con số không. Cuối cùng, bản thân không có chủ đích được sử dụng cho sự ngắn gọn và có lẽ cũng là một gợi ý cho các nhà phát triển trong tương lai mà bạn không bao giờ mong đợi một giá trị không.
vẽ

77
Một trường hợp để sử dụng [weak self]trong yêu cầu mạng không đồng bộ, nằm trong bộ điều khiển chế độ xem yêu cầu đó được sử dụng để đưa vào chế độ xem. Nếu người dùng sao lưu, chúng tôi không còn cần phải xem chế độ xem, chúng tôi cũng không cần tham chiếu đến bộ điều khiển xem.
David James

1
weakcác tham chiếu cũng được đặt thành nilkhi đối tượng được giải phóng. unownedtài liệu tham khảo thì không.
BergQuester

1
Tôi la một chut Nhâm lân. unownedđược sử dụng non-Optionaltrong khi weakđược sử dụng cho Optionalvì vậy chúng ta selfOptionalhay non-optional?
Muhammad Nayab

193

Cập nhật 11/2016

Tôi đã viết một bài viết về việc mở rộng câu trả lời này (nhìn vào SIL để hiểu ARC làm gì), kiểm tra nó ở đây .

Câu trả lời gốc

Các câu trả lời trước không thực sự đưa ra các quy tắc đơn giản về thời điểm sử dụng cái này hơn cái kia và tại sao, vì vậy hãy để tôi thêm một vài điều.

Các cuộc thảo luận không có chủ đích hoặc yếu đi đến một câu hỏi về thời gian tồn tại của biến và kết thúc tham chiếu đến nó.

nhanh nhẹn vs không có chủ

Kịch bản

Bạn có thể có hai tình huống có thể xảy ra:

  1. Việc đóng có cùng thời gian tồn tại của biến, vì vậy việc đóng sẽ chỉ có thể truy cập cho đến khi biến có thể truy cập được . Các biến và đóng có cùng tuổi thọ. Trong trường hợp này, bạn nên khai báo các tham chiếu là không có tên . Một ví dụ phổ biến là được [unowned self]sử dụng trong nhiều ví dụ về việc đóng cửa nhỏ làm một việc gì đó trong bối cảnh của cha mẹ họ và việc không được tham chiếu ở bất kỳ nơi nào khác không tồn tại lâu hơn cha mẹ của họ.

  2. Thời gian đóng là độc lập với một trong các biến, việc đóng vẫn có thể được tham chiếu khi biến không thể truy cập được nữa. Trong trường hợp này, bạn nên khai báo tham chiếu là yếu và xác minh nó không phải là không trước khi sử dụng nó (không bắt buộc mở khóa). Một ví dụ phổ biến về điều này là [weak delegate]bạn có thể thấy trong một số ví dụ về việc đóng tham chiếu một đối tượng đại biểu hoàn toàn không liên quan (suốt đời).

Sử dụng thực tế

Vì vậy, những gì bạn sẽ / thực sự nên sử dụng hầu hết thời gian?

Trích dẫn Joe Groff từ twitter :

Unown là nhanh hơn và cho phép bất biến và nonoptionality.

Nếu bạn không cần yếu, đừng sử dụng nó.

Bạn sẽ tìm thấy nhiều hơn về *hoạt động bên trong chưa được đặt tên ở đây .

* Thường cũng được gọi là chưa được đặt tên (an toàn) để chỉ ra rằng kiểm tra thời gian chạy (dẫn đến sự cố cho các tham chiếu không hợp lệ) được thực hiện trước khi truy cập vào tham chiếu chưa được đặt tên.


26
Tôi mệt mỏi khi nghe lời giải thích của con vẹt "sử dụng tuần nếu bản thân có thể là con số không, sử dụng không có tên khi nó không bao giờ có thể là con số không". Ok chúng tôi đã nhận nó - nghe nó một triệu lần! Câu trả lời này thực sự đào sâu hơn khi nào bản thân có thể không bằng tiếng Anh đơn giản, câu trả lời trực tiếp cho câu hỏi của OP. Cảm ơn lời giải thích tuyệt vời này !!
TruMan1

Cảm ơn @ TruMan1, tôi thực sự đang viết một bài đăng về điều này sẽ sớm kết thúc trên blog của tôi, sẽ cập nhật câu trả lời bằng một liên kết.
Umberto Raimondi

1
Câu trả lời hay, rất thực tế. Tôi được truyền cảm hứng để chuyển một số vars yếu nhạy cảm hiệu suất của tôi thành không có tên bây giờ.
original_username

"Thời gian đóng là độc lập với một trong các biến" Bạn có lỗi đánh máy ở đây không?
Mật ong

1
Nếu một bao đóng luôn có cùng thời gian tồn tại với đối tượng cha, thì số tham chiếu sẽ không được quan tâm bằng cách nào khi đối tượng bị phá hủy? Tại sao bạn không thể sử dụng 'bản thân' trong tình huống này thay vì làm phiền với người không có danh tiếng hoặc yếu đuối?
Truyền thuyết Chiều dài

105

Tôi nghĩ rằng tôi sẽ thêm một số ví dụ cụ thể cho một bộ điều khiển xem. Nhiều lời giải thích, không chỉ ở đây trên Stack Overflow, thực sự tốt, nhưng tôi làm việc tốt hơn với các ví dụ trong thế giới thực (@drewag đã có một khởi đầu tốt về điều này):

  • Nếu bạn có một bao đóng để xử lý một phản hồi từ việc sử dụng các yêu cầu mạng weak, bởi vì chúng tồn tại lâu. Trình điều khiển khung nhìn có thể đóng trước khi yêu cầu hoàn thành để selfkhông còn trỏ đến một đối tượng hợp lệ khi đóng được gọi.
  • Nếu bạn đã đóng mà xử lý một sự kiện trên một nút. Điều này có thể là unowneddo ngay khi bộ điều khiển chế độ xem biến mất, nút và bất kỳ mục nào khác mà nó có thể được tham chiếu selfđi cùng một lúc. Khối đóng cửa cũng sẽ biến mất cùng một lúc.

    class MyViewController: UIViewController {
          @IBOutlet weak var myButton: UIButton!
          let networkManager = NetworkManager()
          let buttonPressClosure: () -> Void // closure must be held in this class. 
    
          override func viewDidLoad() {
              // use unowned here
              buttonPressClosure = { [unowned self] in
                  self.changeDisplayViewMode() // won't happen after vc closes. 
              }
              // use weak here
              networkManager.fetch(query: query) { [weak self] (results, error) in
                  self?.updateUI() // could be called any time after vc closes
              }
          }
          @IBAction func buttonPress(self: Any) {
             buttonPressClosure()
          }
    
          // rest of class below.
     }
    

17
Điều này cần nhiều upvote. Hai ví dụ chắc chắn cho thấy cách đóng nút nhấn sẽ không tồn tại bên ngoài tuổi thọ của bộ điều khiển chế độ xem và do đó có thể sử dụng chưa được đặt tên, nhưng hầu hết các cuộc gọi mạng mà UI cập nhật cần phải yếu.
Tim Fuqua

2
Vì vậy, chỉ để làm rõ, chúng ta luôn luôn sử dụng vô danh hoặc yếu khi gọi bản thân trong một khối đóng cửa? Hay có một thời gian mà chúng ta sẽ không gọi là yếu / không có chủ? Nếu vậy, bạn có thể cung cấp một ví dụ cho điều đó quá?
luke

Cảm ơn bạn rất nhiều.
Shawn Baek

1
Điều này đã cho tôi hiểu sâu sắc hơn về [bản thân yếu đuối] và [bản thân không có chủ đích] Cảm ơn rất nhiều @possen!
Tommy

Điều đó thật tuyệt. Điều gì xảy ra nếu tôi có một hình ảnh động dựa trên sự tương tác của người dùng, nhưng phải mất một lúc để hoàn thành. Và sau đó người dùng chuyển sang một viewContoder khác. Tôi đoán trong trường hợp đó tôi vẫn nên sử dụng weakchứ không unownedphải phải không?
Mật ong

67

Nếu bản thân có thể là con số không, hãy sử dụng [bản thân yếu] .

Nếu bản thân sẽ không bao giờ là con số không trong việc đóng cửa, hãy sử dụng [bản thân không có chủ đích] .

Tài liệu Apple Swift có một phần tuyệt vời với hình ảnh giải thích sự khác biệt giữa việc sử dụng mạnh , yếukhông có dấu trong các lần đóng:

https://developer.apple.com/l Library / content / document / Swift / Contualual / Swift_Programming_Lingu / AutomaticReferenceCounting.html


50

Dưới đây là trích dẫn tuyệt vời từ Diễn đàn nhà phát triển Apple mô tả chi tiết ngon:

unownedđấu unowned(safe)vớiunowned(unsafe)

unowned(safe)là một tài liệu tham khảo không sở hữu khẳng định quyền truy cập mà đối tượng vẫn còn sống. Nó giống như một tài liệu tham khảo tùy chọn yếu được ngầm định mở ra x!mỗi khi nó được truy cập. unowned(unsafe)giống như __unsafe_unretainedtrong ARC, đó là một tài liệu tham khảo không sở hữu, nhưng không có kiểm tra thời gian chạy rằng đối tượng vẫn còn tồn tại khi truy cập, vì vậy các tham chiếu lơ lửng sẽ tiếp cận vào bộ nhớ rác. unownedhiện tại luôn là một từ đồng nghĩa unowned(safe), nhưng mục đích là nó sẽ được tối ưu hóa unowned(unsafe)trong các -Ofast bản dựng khi kiểm tra thời gian chạy bị vô hiệu hóa.

unowned đấu với weak

unownedthực sự sử dụng một thực hiện đơn giản hơn nhiều so với weak. Các đối tượng Swift gốc mang hai số tham chiếu và các unowned tham chiếu tăng số tham chiếu không được đặt tên thay vì số tham chiếu mạnh . Đối tượng được khử khử khi số tham chiếu mạnh của nó đạt đến 0, nhưng nó không thực sự bị hủy cho đến khi số tham chiếu không được đặt tên cũng bằng không. Điều này khiến bộ nhớ bị giữ lâu hơn một chút khi có các tham chiếu không được đặt tên, nhưng đó thường không phải là vấn đề khiunowned được sử dụng bởi vì các đối tượng liên quan nên có tuổi thọ gần bằng nhau, và nó đơn giản hơn và chi phí thấp hơn nhiều so với triển khai dựa trên bảng phụ được sử dụng để xóa các tham chiếu yếu.

Cập nhật: Trong Swift hiện đại weaktrong nội bộ sử dụng cơ chế tương tự như unownedthực hiện . Vì vậy, so sánh này là không chính xác vì nó so sánh Objective-C weakvới Swift unonwed.

Lý do

Mục đích của việc giữ cho bộ nhớ còn sống sau khi sở hữu các tham chiếu đạt 0 là gì? Điều gì xảy ra nếu mã cố gắng làm một cái gì đó với đối tượng bằng cách sử dụng một tham chiếu không được đặt tên sau khi nó bị khử.

Bộ nhớ được giữ sống để số lượng lưu giữ của nó vẫn còn. Bằng cách này, khi ai đó cố gắng giữ lại một tham chiếu mạnh đến đối tượng chưa được đặt tên, thời gian chạy có thể kiểm tra xem số tham chiếu mạnh có lớn hơn 0 để đảm bảo an toàn khi giữ đối tượng đó không.

Điều gì xảy ra với việc sở hữu hoặc không có tài liệu tham khảo được tổ chức bởi đối tượng? Có phải cuộc đời của họ bị tách rời khỏi đối tượng khi nó bị khử cực hay bộ nhớ của họ cũng được giữ lại cho đến khi đối tượng bị giải phóng sau khi tham chiếu không có tên cuối cùng được phát hành?

Tất cả các tài nguyên thuộc sở hữu của đối tượng được phát hành ngay khi tham chiếu mạnh cuối cùng của đối tượng được phát hành và deinit của nó được chạy. Các tham chiếu không được đặt tên chỉ giữ cho bộ nhớ còn sống ngoài mục tiêu với số tham chiếu, nội dung của nó là rác.

Vui mừng hả?


38

Có một số câu trả lời tuyệt vời ở đây. Nhưng những thay đổi gần đây về cách Swift thực hiện các tham chiếu yếu sẽ thay đổi bản thân yếu kém của mọi người so với các quyết định sử dụng bản thân không có chủ đích. Trước đây, nếu bạn cần hiệu suất tốt nhất bằng cách sử dụng bản thân không có chủ lực thì vượt trội so với bản thân yếu đuối, miễn là bạn có thể chắc chắn rằng bản thân sẽ không bao giờ là con số không, bởi vì việc truy cập vào bản thân không được cấp phát nhanh hơn nhiều so với truy cập vào bản thân yếu.

Nhưng Mike Ash đã ghi lại cách Swift đã cập nhật việc triển khai các vars yếu để sử dụng các bảng phụ và cách điều này cải thiện đáng kể hiệu suất bản thân yếu.

https://mikeash.com/pyblog/friday-qa-2017-09-22-swift-4-weak-references.html

Bây giờ không có hình phạt hiệu suất đáng kể đối với bản thân yếu, tôi tin rằng chúng ta nên mặc định sử dụng nó trong tương lai. Lợi ích của bản thân yếu là nó là một tùy chọn, giúp viết mã chính xác dễ dàng hơn nhiều, về cơ bản đó là lý do Swift là một ngôn ngữ tuyệt vời như vậy. Bạn có thể nghĩ rằng bạn biết những tình huống nào là an toàn cho việc sử dụng bản thân không có chủ, nhưng kinh nghiệm của tôi khi xem xét rất nhiều mã nhà phát triển khác là, hầu hết là không. Tôi đã sửa rất nhiều sự cố trong đó bản thân không được đặt tên đã bị xử lý, thường là trong các tình huống khi một luồng nền hoàn thành sau khi bộ điều khiển bị hủy.

Lỗi và sự cố là phần tốn thời gian, đau đớn và tốn kém nhất của lập trình. Làm hết sức mình để viết mã chính xác và tránh chúng. Tôi khuyên bạn nên biến nó thành một quy tắc để không bao giờ ép buộc các tùy chọn không mong muốn và không bao giờ sử dụng bản thân không có chủ quyền thay vì bản thân yếu. Bạn sẽ không mất bất cứ thứ gì thiếu trong những lần ép buộc và bản thân không có chủ đích thực sự an toàn. Nhưng bạn sẽ đạt được rất nhiều từ việc loại bỏ khó khăn để tìm và gỡ lỗi các sự cố và lỗi.


Cảm ơn bạn đã cập nhật và Amen trên đoạn cuối cùng.
phương châm

1
Vì vậy, sau những thay đổi mới Có khi weaknào không thể sử dụng thay thế cho một unowned?
Mật ong

4

Theo Apple-doc

  • Các tham chiếu yếu luôn thuộc loại tùy chọn và tự động trở thành con số không khi đối tượng mà chúng tham chiếu bị hủy.

  • Nếu tham chiếu bị bắt sẽ không bao giờ trở thành con số không, thì nó phải luôn được ghi lại dưới dạng tham chiếu không được đặt tên, thay vì tham chiếu yếu

Thí dụ -

    // if my response can nil use  [weak self]
      resource.request().onComplete { [weak self] response in
      guard let strongSelf = self else {
        return
      }
      let model = strongSelf.updateModel(response)
      strongSelf.updateUI(model)
     }

    // Only use [unowned self] unowned if guarantees that response never nil  
      resource.request().onComplete { [unowned self] response in
      let model = self.updateModel(response)
      self.updateUI(model)
     }

0

Nếu không có điều nào ở trên có ý nghĩa:

tl; dr

Giống như một implicitly unwrapped optional, Nếu bạn có thể đảm bảo rằng tài liệu tham khảo sẽ không còn ở thời điểm sử dụng, hãy sử dụng không có tên. Nếu không, thì bạn nên sử dụng yếu.

Giải trình:

Tôi lấy ra như sau: tại liên kết yếu . Từ những gì tôi thu thập được, bản thân không có danh tiếng không thể là con người nhưng bản thân yếu đuối có thể, và bản thân không được biết đến có thể dẫn đến những con trỏ lơ lửng ... một cái gì đó khét tiếng trong Objective-C. Hy vọng nó giúp

"UNOWNED Các tài liệu tham khảo yếu và không có chủ đề hoạt động tương tự nhưng KHÔNG giống nhau."

Tài liệu tham khảo chưa được đặt tên, như tài liệu tham khảo yếu, không làm tăng số lượng giữ lại của đối tượng được giới thiệu. Tuy nhiên, trong Swift, một tài liệu tham khảo không có tên có thêm lợi ích của việc không phải là Tùy chọn . Điều này làm cho chúng dễ quản lý hơn là sử dụng ràng buộc tùy chọn. Điều này không giống với các tùy chọn không bị che giấu. Ngoài ra, các tài liệu tham khảo không có chủ đề là khác không . Điều này có nghĩa là khi đối tượng được giải phóng, nó không thoát ra khỏi con trỏ. Điều này có nghĩa là trong một số trường hợp, việc sử dụng các tài liệu tham khảo không được nêu tên có thể dẫn đến con trỏ lơ lửng. Đối với các bạn mọt sách ngoài kia nhớ những ngày Objective-C như tôi, bản đồ tham chiếu chưa được đặt tên thành các tham chiếu không an toàn_unretained.

Đây là nơi nó có một chút khó hiểu.

Cả hai tài liệu tham khảo yếu và không có chủ đề đều không làm tăng số lượng giữ lại.

Cả hai đều có thể được sử dụng để phá vỡ các chu kỳ giữ lại. Vậy khi nào chúng ta sử dụng chúng?!

Theo tài liệu của Apple :

Sử dụng một tham chiếu yếu bất cứ khi nào nó có giá trị để tham chiếu đó trở thành con số không tại một thời điểm nào đó trong suốt vòng đời của nó. Ngược lại, sử dụng một tham chiếu chưa được đặt tên khi bạn biết rằng tham chiếu đó sẽ không bao giờ được thực hiện một khi nó đã được đặt trong quá trình khởi tạo.


0
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let controller = storyboard.instantiateViewController(withIdentifier: "AnotherViewController")
        self.navigationController?.pushViewController(controller, animated: true)

    }

}



import UIKit
class AnotherViewController: UIViewController {

    var name : String!

    deinit {
        print("Deint AnotherViewController")
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        print(CFGetRetainCount(self))

        /*
            When you test please comment out or vice versa

         */

//        // Should not use unowned here. Because unowned is used where not deallocated. or gurranted object alive. If you immediate click back button app will crash here. Though there will no retain cycles
//        clouser(string: "") { [unowned self] (boolValue)  in
//            self.name = "some"
//        }
//


//
//        // There will be a retain cycle. because viewcontroller has a strong refference to this clouser and as well as clouser (self.name) has a strong refferennce to the viewcontroller. Deint AnotherViewController will not print
//        clouser(string: "") { (boolValue)  in
//            self.name = "some"
//        }
//
//


//        // no retain cycle here. because viewcontroller has a strong refference to this clouser. But clouser (self.name) has a weak refferennce to the viewcontroller. Deint AnotherViewController will  print. As we forcefully made viewcontroller weak so its now optional type. migh be nil. and we added a ? (self?)
//
//        clouser(string: "") { [weak self] (boolValue)  in
//            self?.name = "some"
//        }


        // no retain cycle here. because viewcontroller has a strong refference to this clouser. But clouser nos refference to the viewcontroller. Deint AnotherViewController will  print. As we forcefully made viewcontroller weak so its now optional type. migh be nil. and we added a ? (self?)

        clouser(string: "") {  (boolValue)  in
            print("some")
            print(CFGetRetainCount(self))

        }

    }


    func clouser(string: String, completion: @escaping (Bool) -> ()) {
        // some heavy task
        DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
            completion(true)
        }

    }

}

Nếu bạn không chắc chắn về [unowned self] sau đó sử dụng [weak self]

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.