2014-09-22 20 views
10

Tôi đang cố gắng giải quyết chu trình tham chiếu mạnh mẽ đóng cửa trong Swift.
Trong mã bên dưới, đối tượng được giữ lại bởi bộ điều khiển chế độ xem sở hữu. ProgressHUDUIView cũng được giữ lại bởi bộ điều khiển chế độ xem sở hữu. ProgressHUD bị rò rỉ mỗi lần xử lý hoàn thành được gọi. Khi sử dụng tính năng chụp đóng cửa mới, việc khai báo tự yếu hoặc không được công nhận không giải quyết được sự rò rỉ bộ nhớ.Đóng cửa nhanh - Chụp ảnh tự yếu

object.setCompletionHandler { [weak self] (error) -> Void in 
    if(!error){ 
     self?.tableView.reloadData() 
    } 
    self?.progressHUD?.hide(false) 
} 

Tuy nhiên, nếu tôi tuyên bố một var yếu để tự bên ngoài của việc đóng cửa, nó sửa chữa rò rỉ bộ nhớ, như thế này:

weak var weakSelf = self 
object.setCompletionHandler { (error) -> Void in 
    if(!error){ 
     weakSelf?.tableView.reloadData() 
    } 
    weakSelf?.progressHUD?.hide(false) 
} 

Bất kỳ ý tưởng là tại sao điều này không làm việc với chụp Swift ?

+0

không nên có một duy trì chu kỳ – newacct

Trả lời

-3

Hãy thử như sau:

object.setCompletionHandler { [unowned self] (error) ->() in 
    if(!error){ 
     weakSelf?.tableView.reloadData() 
    } 
    weakSelf?.progressHUD?.hide(false) 
} 
+0

Như đã đề cập trong các bài bản gốc, không phải yếu hoặc không có chủ giải quyết rò rỉ bộ nhớ. Cảm ơn mặc dù. –

11

Nếu bạn gán một đóng thành tài sản của một cá thể của lớp, và việc đóng cửa chụp mà dụ bằng cách tham khảo các ví dụ hoặc các thành viên của nó, bạn sẽ tạo ra một chu kỳ tài liệu tham khảo mạnh mẽ giữa đóng cửa và thể hiện. Swift sử dụng các danh sách chụp để phá vỡ các chu trình tham chiếu mạnh này. source Apple

source sketchyTech Trước hết, điều quan trọng là làm cho rõ ràng rằng toàn bộ vấn đề này chỉ liên quan đến việc đóng cửa nơi chúng ta đang gán "đóng cửa để một tài sản của một cá thể của lớp". Hãy ghi nhớ điều này với mỗi quy tắc. Các quy tắc:

  1. sử dụng chụp yếu nếu cá thể lớp hoặc tài sản là một tùy chọn
  2. sử dụng không có chủ nếu cá thể lớp hoặc tài sản là không bắt buộc và không bao giờ có thể được thiết lập để nil
  3. "bạn phải ... sử dụng từ khóa, ngay cả khi bạn bỏ qua tên tham số, loại thông số và loại trả về "

Khi trả lời câu hỏi của bạn, không nên có chu kỳ lưu giữ.

4

Bạn nói rằng progressHUD được giữ lại bởi bộ điều khiển xem sở hữu (tự) và bạn tham khảo nó trong việc đóng cửa của bạn ... để thêm nó vào danh sách thu hồi và sau đó sử dụng các biến bị bắt trong việc đóng cửa như sau:

object.setCompletionHandler { [weak self] (error) -> Void in 
    if(!error){ 
     self?.tableView.reloadData() 
    } 
    self?.progressHUD.hide(false) 
} 
+0

Các tham chiếu không được thừa nhận được ẩn hoàn toàn vì vậy 'self? .tableView' sẽ được thay đổi thành' self.tableView'. –

+0

bạn đúng @zxzxlch, tôi đã chỉnh sửa giải pháp của mình bằng cách thay đổi tự unowned thành tự yếu, và giảm tiến độ từ danh sách chụp. Không nên có chu kỳ giữ lại. – dferrero

-1

Đây là cách tôi đã làm điều đó:

object.setCompletionHandler { [weak self] (error) -> Void in 
    if let weakSelf = self { 
     if (!error) { 
      weakSelf.tableView.reloadData() 
     } 

     weakSelf.progressHUD?.hide(false) 
    } 
} 
+3

Đó là chính xác ngược. Đổi tên 'weakSelf' thành 'strongSelf'. 'Let' giúp bạn tham khảo mạnh mẽ. –

Các vấn đề liên quan