Làm cách nào để tạo một hàm với trình xử lý hoàn thành trong Swift?


Câu trả lời:


174

Giả sử bạn có chức năng tải xuống để tải xuống tệp từ mạng và muốn được thông báo khi tác vụ tải xuống hoàn tất.

typealias CompletionHandler = (success:Bool) -> Void

func downloadFileFromURL(url: NSURL,completionHandler: CompletionHandler) {

    // download code.

    let flag = true // true if download succeed,false otherwise

    completionHandler(success: flag)
}

// How to use it.

downloadFileFromURL(NSURL(string: "url_str")!, { (success) -> Void in

    // When download completes,control flow goes here.
    if success {
        // download success
    } else {
        // download fail
    }
})

Hy vọng nó giúp.


2
Điều này sẽ hoạt động tốt, nhưng vì tò mò hơn, tôi đã tự hỏi liệu bạn có thể bằng cách nào đó viết một trình xử lý hoàn thành vào hàm của mình không.
traw1233

1
Xin chào Floks, tôi muốn gọi nó là CompletionHandler từ một hàm khác, vậy làm cách nào để đạt được điều này ??
Himanshu jamnani

bất kỳ ví dụ nào cho mục tiêu c
Xcodian Solangi

Khi tôi gọi nó bằng một lớp khác, nó không gieo tham số thành công của trình xử lý hoàn thành.
Chandni

85

Tôi khó hiểu câu trả lời vì vậy tôi giả định rằng bất kỳ người mới bắt đầu nào khác như tôi cũng có thể gặp vấn đề giống tôi.

Giải pháp của tôi thực hiện tương tự như câu trả lời trên cùng nhưng hy vọng rõ ràng và dễ hiểu hơn một chút cho người mới bắt đầu hoặc những người chỉ gặp khó khăn trong việc hiểu nói chung.

Để tạo một hàm với trình xử lý hoàn thành

func yourFunctionName(finished: () -> Void) {

     print("Doing something!")

     finished()

}

để sử dụng chức năng

     override func viewDidLoad() {

          yourFunctionName {

          //do something here after running your function
           print("Tada!!!!")
          }

    }

Đầu ra của bạn sẽ là

Đang làm gì đó

Tada !!!

Hi vọng điêu nay co ich!


80

Ví dụ về Swift 4.0 đơn giản:

func method(arg: Bool, completion: (Bool) -> ()) {
    print("First line of code executed")
    // do stuff here to determine what you want to "send back".
    // we are just sending the Boolean value that was sent in "back"
    completion(arg)
}

Làm thế nào để sử dụng nó:

method(arg: true, completion: { (success) -> Void in
    print("Second line of code executed")
    if success { // this will be equal to whatever value is set in this method call
          print("true")
    } else {
         print("false")
    }
})

12

Chúng ta có thể sử dụng Closures cho mục đích này. Hãy thử những điều sau

func loadHealthCareList(completionClosure: (indexes: NSMutableArray)-> ()) {
      //some code here
      completionClosure(indexes: list)
}

Tại một số điểm, chúng ta có thể gọi hàm này như hình dưới đây.

healthIndexManager.loadHealthCareList { (indexes) -> () in
            print(indexes)
}

Vui lòng tham khảo liên kết sau để biết thêm thông tin về Closures .

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html


5

Swift 5.0 +, Đơn giản và Ngắn gọn

thí dụ:

Phong cách 1

    func methodName(completionBlock: () -> Void)  {

          print("block_Completion")
          completionBlock()
    }

Phong cách 2

    func methodName(completionBlock: () -> ())  {

        print("block_Completion")
        completionBlock()
    }

Sử dụng:

    override func viewDidLoad() {
        super.viewDidLoad()
        
        methodName {

            print("Doing something after Block_Completion!!")
        }
    }

Đầu ra

block_Completion

Làm gì đó sau Block_Completion !!


0

Tôi hơi bối rối về trình xử lý hoàn thành tùy chỉnh. Trong ví dụ của bạn:

Giả sử bạn có chức năng tải xuống để tải xuống tệp từ mạng và muốn được thông báo khi tác vụ tải xuống hoàn tất.

typealias CompletionHandler = (success:Bool) -> Void

func downloadFileFromURL(url: NSURL,completionHandler: CompletionHandler) {

    // download code.

    let flag = true // true if download succeed,false otherwise

    completionHandler(success: flag)
}

Di // download codechúc của bạn vẫn được chạy không đồng bộ. Tại sao mã không được chuyển thẳng đến của bạn let flag = truecompletion Handler(success: flag)không đợi mã tải xuống của bạn hoàn tất?


Cuối cùng, một cái gì đó phải ngồi và đợi mã chạy, nó không phải là một tòa tháp khổng lồ của những con voi không đồng bộ ở tất cả các con đường đi xuống. "Ran không đồng bộ" có nghĩa là có hai luồng. Một trong số họ ngồi và chờ đợi nhiệm vụ được thực hiện, người kia tiếp tục và không. Trình xử lý hoàn thành được gọi, hoặc ít nhất được lên lịch để được gọi, ở cuối luồng thực hiện công việc.
Crowman

0

Ngoài trên: Trailing đóng cửa có thể được sử dụng.

downloadFileFromURL(NSURL(string: "url_str")!)  { (success) -> Void in

  // When download completes,control flow goes here.
  if success {
      // download success
  } else {
    // download fail
  }
}
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.