2016-12-10 2 views
0
@IBAction func sendSweet(sender: UIBarButtonItem) { 

    var inputTextField: UITextField? 
    let alert = UIAlertController(title: "New sweet", message: "Enter a sweet", preferredStyle: .alert) 
    alert.addTextField { (textField: UITextField) in 
     textField.placeholder = "Your sweet" 
     inputTextField = textField 
    } 

    let sendAction = UIAlertAction(title: "Send", style: .default, handler: { 
     [weak self] (alertAction: UIAlertAction) in 
     guard let strongSelf = self else { return } 

     if inputTextField?.text != "" { 
      let newSweet = CKRecord(recordType: "Sweet") 
      newSweet["content"] = inputTextField?.text as CKRecordValue? 

      let publicData = CKContainer.default().publicCloudDatabase 
      publicData.save(newSweet, completionHandler: { 
       (record: CKRecord?, error: Error?) in 

       if error == nil { 
        // we want ui code to dispatch asychronously in main thread 
        DispatchQueue.main.async { 
         strongSelf.tableView.beginUpdates() 
         strongSelf.sweets.insert(newSweet, at: 0) 
         let indexPath = IndexPath(row: 0, section: 0) 
         strongSelf.tableView.insertRows(at: [indexPath], with: .top) 
         strongSelf.tableView.endUpdates() 
        } 
       } else { 
        if let error = error { 
         print(error.localizedDescription) 
         return 
        } 
       } 
      }) 
     } 
    }) 

    alert.addAction(sendAction) 
    alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) 
    present(alert, animated: true, completion: nil) 

} 

, 나는중첩 콜백 강한 참조주기 나는이 콜백 지옥이

  1. 콜백 지옥의 매우 상단에있는이 [weak self] & guard let strongSelf 공약수의를 통해 모든 밖으로 강한 참조주기를 방지합니까 알고 싶어 비동기 콜백. 나는 콜백 내부에서 참조하는 객체가 성공적으로 deinit을 참조 할 수 있다면 강한 참고주기가없는 것을 나타내는 좋은 징조를 의미하는 책에서 또 하나의 게시물을 읽었다.

  2. 이런 종류의 콜백을 방지하려면 어떻게해야합니까? 내가 놓친 일부 독서물이나 주제로 안내 할 수 있습니까? 자바 스크립트의 약속 체인 연결 구문 같은 건?

답변

1

내가 알 수있는 한 유지주기가 없으므로 self을 약화 할 필요가 없습니다. 당신은 확실히 모든 블록에서 방어 할 수 있습니다.

인스턴스 (self)에 클로저에 대한 참조가 없기 때문에 보존주기가 없습니다. 특히 sendAction으로, sendActionsendSweet 함수 안에서 선언됩니다. 인스턴스의 속성으로 함수의 let sendAction = ... 외부 이동한다면

class MyView: UIView { 
    let str = "some variable to have somsthing to use self with" 

    func foo() { 
     let ba = { 
      // no problem. The instance of MyView (self) does not hold a (strong) reference to ba 
      self.str.trimmingCharacters(in: CharacterSet.alphanumerics) 
     } 

     ba() 
    } 
} 

, 당신은 비록 참조주기를 가질 것이다. 이 경우 인스턴스 ( self)는 sendAction에 강한에 refrence있을 것와 sendAction 폐쇄는 인스턴스 ( self)에 대한 강한 참조 것 :

자기 < -> {자기. ...} 일명 sendAction. 이 경우

class MyView: UIView { 
    let str = "asd" 
    // Problem. 
    // The instance of MyView (self) does hold a (strong) reference to ba ... 
    let ba:() -> Void 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     ba = {  
      // ... while ba holds a strong reference to the instance (self)   
      self.str.trimmingCharacters(in: CharacterSet.alphanumerics) 
     } 
    } 

    func foo() { 
     ba() 
    } 
} 

당신은 당신이 그랬던 것처럼 weak이 폐쇄 내 self을 ifying하여 고리를 끊어야합니다. 콜백 지옥의이 종류를 방지하는 방법

, 당신은 몇 가지 독서 자료

체크 아웃 DispatchGroup의 날을 초래할 수 있습니다.

(Apple Documentation)

+0

이, 참조 사이클 만 내가 읽고 다른 블로그 게시물을 생각 나게 객체 계층에서 두 방향으로 참조하려고 할 때 발생하지만 단일 방향으로 참조되지는 않습니다. –

+0

즉 '주기'의 정의. – shallowThought

0

내 문제 # 2

https://github.com/duemunk/Async

예에 꽤 깔끔한 해결책을 찾을 수는 니펫을 :

Async.userInitiated { 
    return 10 
}.background { 
    return "Score: \($0)" 
}.main { 
    label.text = $0 
}