2015-09-15 20 views
19

Có một similar question về cách weakify/strongify tự, được trả lời, nhưng tôi đang tự hỏi làm thế nào để sử dụng "tự" mà không rightward-trôi do if let:Làm thế nào để "strongify" tự tùy chọn sử dụng bảo vệ trong Swift 2.0

Welcome to Apple Swift version 2.0 (700.0.59 700.0.72). Type :help for assistance. 
    2> import Foundation 
    3> class Foo { 
    4.  func guardOptSelf() ->() throws -> Void { 
    5.   return { [weak self] in 
    6.    guard let self = self else { throw NSError(domain: "I was destroyed!", code: 1, userInfo: nil) } 
    7.    self.doSomethingNonOptionalSelf()   
    8.   } 
    9.  } 
    10. } 
repl.swift:6:19: error: pattern matching in a condition requires the 'case' keyword 
      guard let self = self else { throw NSError(domain: "I was destroyed!", code: 1, userInfo: nil) } 
       ^
        case 
repl.swift:6:23: error: binary operator '~=' cannot be applied to two 'Foo?' operands 
      guard let self = self else { throw NSError(domain: "I was destroyed!", code: 1, userInfo: nil) } 

Trả lời

30

Bạn can shadow self; bạn chỉ cần backticks để chỉ ra rằng "bạn biết những gì bạn đang làm". Ví dụ:

foo.doSomethingAsyncWithBar(bar) { [weak self] result in 
    guard let `self` = self else { return } 
    self.receivedResult(result) 
} 

Hoặc, trong ví dụ của bạn:

2> import Foundation 
3> class Foo { 
4.  func guardOptSelf() ->() throws -> Void { 
5.   return { [weak self] in 
6.    guard let `self` = self else { throw NSError(domain: "I was destroyed!", code: 1, userInfo: nil) } 
7.    self.doSomethingNonOptionalSelf()   
8.   } 
9.  } 
10. } 
+1

Ah, đẹp quá! Không biết về tính năng ngôn ngữ ngược. Có vẻ như điều này cũng không bị ảnh hưởng bởi các thiết lập cảnh báo của trình biên dịch đối với biến đổ bóng, mà các thư viện như libextobjc phải ngăn chặn việc triển khai @ weakify/strongify –

+9

Mặc dù điều này có hiệu quả, nó không đáng tin cậy như Chris Lattner của Apple đã nói nó như là một 'lỗi trình biên dịch' - và vì đó là một lỗi, nó có thể được sửa chữa trong tương lai: https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160118/007425.html –

+0

Tôi không chắc chắn nếu tôi hiểu câu hỏi hoàn toàn cũng như câu trả lời của bạn. ** 1) ** Câu hỏi đặt ra là hỏi 'chúng ta nên làm gì nếu một 'self' bị bắt bị loại bỏ sớm trước khi chúng ta hoàn thành nó? ** 2) ** Để làm như vậy, chúng tôi phải thực hiện thêm 1 bước, tức là nhiều hơn so với thông thường '[tự yếu]'. Chúng ta nên nắm bắt nó bằng cách sử dụng tham chiếu mạnh mẽ 'guard let' ** 3) ** để làm cho mọi thứ trở nên đẹp và mượt mà, chúng ta sử dụng backticks để' self' trở nên không được mở, bởi vì sử dụng 'weak' sẽ chuyển' self' thành tùy chọn & chúng ta cũng có thể giữ cùng tên * self *? – Honey

3

guard let `self` = self là một compiler bug as stated by Chris Lattner tôi sẽ cố gắng để tránh nó. Trong ví dụ của bạn, bạn có thể chỉ sử dụng chuỗi tùy chọn đơn giản:

return { [weak self] in 
    self?.doSomethingNonOptionalSelf()   
} 

Đôi khi bạn có thể cần sử dụng tự làm tham số. Trong trường hợp như vậy, bạn có thể sử dụng flatMap (trên một loại không bắt buộc):

{ [weak self] in 
    self.flatMap { $0.delegate?.tableView($0, didSelectRowAt: indexPath) } 
} 

Trong trường hợp bạn cần phải làm điều gì đó phức tạp hơn bạn có thể sử dụng if let xây dựng:

{ [weak self] in 
    if let strongSelf = self { 
     // Do something more complicated using strongSelf 
    } 
} 

hoặc guard let xây dựng:

{ [weak self] in 
    guard let strongSelf = self else { return } 

    // Do something more complicated using strongSelf 
} 

hoặc bạn có thể tạo phương thức riêng tư:

{ [weak self] in 
    self?.doSomethingMoreComplicated() 
} 

... 

private func doSomethingMoreComplicated() { 
    // Do something more complicated 
} 
+0

Cảm ơn các lựa chọn thay thế khác nhau. Chúng ta có thể thêm 'guard let strongSelf = self else {return}'. Đó là một sự xấu hổ không có một cách ngắn hơn để thể hiện thành ngữ phổ biến này. Ví dụ một cái gì đó như '[nếu tự] trong self.method()' nơi đóng cửa được thực hiện nếu tự không phải là không. –

+0

Cảm ơn @FerranMaylinch, tôi đã chỉnh sửa câu trả lời để bao gồm cả 'guard let'. –

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