2016-10-05 38 views
6

Tôi đã hàm sau trong Swift 3() có nghĩa là gì trong Swift?

func fetchOrders(_ completionHandler: (_ orders: [Order]) -> Void) 
    { 
    ordersStore.fetchOrders { (orders:() throws -> [Order]) -> Void in 
     do { 
     let orders = try orders() 
     completionHandler(orders) 
     } catch { 
     completionHandler([]) 
     } 
    } 
    } 
  1. không _ completionHandler luận trong fetchOrders nghĩa là gì?
  2. (orders:() throws -> [Order]) có nghĩa là gì?

PS: Tôi mới vào iOSSwift

+2

Reading chương "Chức năng" trong cuốn sách Swift tham khảo có thể hữu ích ... –

Trả lời

7

Có khá nhiều ở đây, vì vậy chúng tôi sẽ phá vỡ nó xuống một mảnh tại một thời điểm:

func fetchOrders(_ completionHandler: (_ orders: [Order]) -> Void) 
  • Đây là một chức năng gọi là fetchOrders.
  • Nó có một tham số (completionHandler) và không trả về gì cả.
  • Đầu tiên _ cho biết không có "tên bên ngoài" của tham số đầu tiên. Tức là, bạn không phải gắn nhãn nó (trên thực tế, bạn không thể). (Vì những lý do không thực sự quan trọng ở đây, tôi tin rằng tác giả đã phạm sai lầm khi sử dụng _ ở đó và tôi sẽ không làm điều đó.)
  • completionHandler là "tên nội bộ", thông số được gọi bên trong chức năng.
  • Loại completionHandler(_ orders: [Order]) -> Void. Chúng ta sẽ phá vỡ nó ngay bây giờ.
    • Giá trị này là đóng cửa phải mất [Order] (mảng Order) và trả lại Void. Về cơ bản, điều này có nghĩa là "trả về không có gì" nhưng theo nghĩa đen nghĩa là nó trả về bộ trống rỗng ().
    • Cú pháp _ orders: thực tế là nhận xét. Về nguyên tắc, _ là tên bên ngoài (nhưng đó là tên ngoài hợp pháp duy nhất để đóng) và orders là tên nội bộ, nhưng trên thực tế, các thông số đóng không có tên theo bất kỳ cách nào có ý nghĩa, vì vậy đây hoàn toàn là thông tin.
    • Tôi tin rằng đây là việc sử dụng kém hệ thống nhận xét tham số đóng.Vì orders cho chúng tôi biết không có gì hơn [Order], tôi đã bỏ qua nó và tạo loại chỉ ([Order]) -> Void.

Bây giờ chúng ta sẽ chuyển sang dòng tiếp theo:

ordersStore.fetchOrders { (orders:() throws -> [Order]) -> Void in 
  • này gọi phương thức fetchOrders trên ordersStore. Chúng ta có thể nói từ mã này rằng fetchOrders có tham số đóng. Điều này được gọi là cú pháp "trailing closure" trong Swift, và là lý do tại sao tôi sẽ không sử dụng _ cho việc đóng của chúng ta. Với cú pháp đóng dấu, tên bên ngoài của tham số là không cần thiết.
  • Tác giả đã cung cấp thông tin loại ở đây có thể không cần thiết, nhưng chúng tôi vẫn có thể khám phá thông tin đó. Điều này có thể có thể đã được viết như chỉ { orders in, nhưng sau đó người đọc có thể sẽ ngạc nhiên bởi mã hơi bất thường này.
    • Chúng tôi đã được thông qua một đóng cửa được gọi là orders không mất gì và trả lại [Order] hoặc ném lỗi. Về cơ bản đây là một cách để nói rằng fetchOrders có thể thất bại.
    • Tác giả đang làm việc xung quanh một sự lúng túng trong hệ thống throws của Swift, không có cách tự nhiên để thể hiện một hành động không đồng bộ có thể không thành công. Đây là một cách để sửa chữa nó; bạn vượt qua một chức năng ném (tức là có thể thất bại). Tôi không ủng hộ cách tiếp cận này, tôi ủng hộ việc sử dụng Result enum cho trường hợp này vì tôi nghĩ rằng nó cân tốt hơn và tránh các tác dụng phụ không mong muốn, nhưng đó là điểm đáng tranh cãi (và cộng đồng Swift đã không thực sự quyết định cách xử lý vấn đề này vấn đề thường gặp).

này tất cả đưa chúng ta đến:

do { 
    let orders = try orders() 
    completionHandler(orders) 
    } catch { 
    completionHandler([]) 
    } 
  • Đây là nơi đóng orders được đánh giá. (Điều này rất quan trọng, nếu orders có các tác dụng phụ, đây là khi chúng xảy ra, có thể nằm trên một hàng đợi khác so với dự định. Đó là một lý do tôi không ưa thích mẫu này.) Nếu việc đóng thành công, chúng tôi trả về kết quả của nó , nếu không, chúng tôi trả lại [] trong số catch bên dưới.
    • Trong đặc biệt trường hợp này, cách tiếp cận throws là hơi ngớ ngẩn, bởi vì nó âm thầm dẹp vào [] mà không cần nhắn tin đăng nhập. Nếu chúng tôi không quan tâm đến lỗi, thì sự cố sẽ chỉ cần trả lại [] để bắt đầu và không bị nhầm lẫn với throws. Nhưng có thể những người gọi khác kiểm tra lỗi.
  • Trong cả hai trường hợp, chúng tôi gọi kết thúc là completionHandler, kết nối lại với người gọi ban đầu của chúng tôi.

/catch block làm này có thể đã được đơn giản hơn bằng văn bản như:

let completedOrders = try? orders() ?? [] 
completionHandler(completedOrders) 

Điều này làm cho nó rõ ràng rằng chúng ta đang bỏ qua lỗi bằng cách chuyển nó thành một tùy chọn, và tránh việc lặp lại code của cuộc gọi đến completionHandler.

(Tôi chỉ cần thêm thêm let ràng buộc để làm cho đoạn code một chút dễ dàng hơn để đọc;. Nó không cần thiết)

+0

Điều này không thể được giải thích tốt hơn. –

+0

Ai đó có thể giải thích, làm thế nào hay tại sao mẫu này có thể có trình xử lý hoàn thành kết thúc trên một hàng đợi khác? – Jay

+1

@Jay Trên hàng đợi khác với cái gì? (Không có "hàng đợi hiện tại" trong GCD. Đây là một sự hiểu lầm rất phổ biến về cách hàng đợi hoạt động.) Nếu phương thức thực hiện công việc trên một luồng nền (một luồng không phải là một hàng đợi), nó sẽ thực thi trình xử lý hoàn thành trên đó khi nó hoàn thành. Việc gửi đến hàng đợi yêu cầu thêm sự phức tạp; hoặc bạn cần phải vượt qua nó một hàng đợi, hoặc nó phải hứa hẹn một số hàng đợi cụ thể (chẳng hạn như hàng đợi chính). Trước đây là hơi phổ biến ở Cocoa. Loại thứ hai phổ biến hơn trong các khuôn khổ của bên thứ 3, nhưng thường không mong muốn. –

2

Đối số completionHandler có nghĩa là thông số dự kiến ​​(tên completionHandler) phải là một chức năng mà phải mất một danh sách các đối tượng Order và không trả lại bất kỳ giá trị.

2

completionHandler là tên biến. Trong ví dụ cụ thể này, biến này là callback. Bạn biết đó là hàm gọi lại vì (orders: [Order]) -> Void là kiểu dữ liệu của nó; trong trường hợp cụ thể này, kiểu dữ liệu cho biết là một hàm nhận một mảng các đối tượng Order trong một biến số _orders và không có giá trị trả về (phần Void).

TL; DR:

  1. đó là tên biến, các loại:
  2. chức năng mà nhận được một loạt các Order như một tham số và hoạt động như một callback.
Các vấn đề liên quan