2015-05-08 17 views
7

Tôi tương đối mới đối với Swift và Xcode nói chung và tôi thấy rất khó khăn khi cố gắng tìm ra điều này.Chỉ chạy mã sau khi chức năng không đồng bộ hoàn thành việc thực thi

Tôi đang phát triển một ứng dụng sử dụng máy chủ phụ trợ Parse.com. Để không chặn luồng chính, bất cứ khi nào ứng dụng tải xuống bất kỳ thứ gì từ máy chủ, ứng dụng sẽ được thực hiện trên một chuỗi khác, không đồng bộ. Tuy nhiên, phần còn lại của mã vẫn tiếp tục thực thi trên luồng chính và nó bị treo khi dữ liệu được cho là từ máy chủ chưa được tải xuống. Tôi muốn biết cách gọi các hàm để chạy sau khi hàm không đồng bộ kết thúc, và điều này phải được thực hiện cho các hàm trong các tệp riêng biệt.

Tôi đọc rằng đóng cửa có thể giúp với điều này, nhưng tôi thấy có cú pháp rất khó và giải thích sẽ được đánh giá cao. Nhưng mọi cách sẽ rất hữu ích.

Cảm ơn

Trả lời

13

Vâng, bạn chỉ cần gọi hàm vào cuối của callback không đồng bộ. Đó là khi gọi lại không đồng bộ đã kết thúc - đó là khi mọi thứ khác trong gọi lại không đồng bộ đã kết thúc! Vì vậy, ví dụ:

func myMethod() { 
    // ... code ... 
    somebody.doSomethingWith(someObject, asynchronousCallback: { 
     (thing, otherThing) in 
     // ... do whatever 
     // --> CALL THE FUNCTION! 
    }) 
    // ... code ... 
} 

Nếu vấn đề là bạn không biết gì chức năng để gọi điện thoại, bạn có thể cấu hình chức năng xung quanh bạn/đối tượng để ai đó có thể tay bạn một hàm mà sau đó những gì bạn gọi ngay tại chỗ tôi đã nói "gọi hàm" ở trên.

Ví dụ:

func myMethod(f:() ->()) { // we receive the function as parameter 
    // ... code ... 
    somebody.doSomethingWith(someObject, asynchronousCallback: { 
     (thing, otherThing) in 
     // ... do whatever 
     // --> CALL THE FUNCTION, by saying: 
     f() 
    }) 
    // ... code ... 
} 
+0

bạn có thể giải thích làm thế nào để giao một chức năng? Tôi hiểu trước rằng bạn chạy hàm mà bạn đã viết "gọi hàm", nhưng chức năng, như tôi đã nói, nằm trong một tệp khác. Trường hợp cụ thể mà tôi đang làm việc ngay bây giờ là tôi đã viết một hàm kiểm tra đầu tiên nếu đối tượng được tìm kiếm nằm trong kho dữ liệu cục bộ và nếu không, nó sẽ kiểm tra máy chủ. Vì tôi muốn điều này chạy khắp mọi nơi, tôi đặt nó vào một tập tin riêng biệt. Nhưng tôi vẫn cần nó để gọi các hàm trong lớp gọi là nó. Cảm ơn một lần nữa. – Acoop

+0

Tôi chắc chắn có thể giải thích nó _linguistically_. Trong Swift, các hàm là các công dân hạng nhất, do đó hàm A có thể thực hiện chức năng B để hàm C, có thể lưu trữ hàm B. Sau đó, hàm C hoặc một số hàm khác có quyền truy cập vào hàm B được lưu trữ có thể _call_ function B. Đó là cách tất cả các cuộc gọi lại hoạt động. Khi bạn nói 'UIView.animateWithDuration() {...}', đó là những gì bạn đang chuyển sang Cocoa - một hàm mà nó sẽ gọi để thực hiện hoạt ảnh. Xem thêm cuốn sách của tôi: http://www.apeth.com/swiftBook/ch02.html#_function_as_value – matt

+0

Tuy nhiên, cách bạn chọn thực hiện _architecturally_ tùy thuộc vào bạn. Trong ví dụ trên, 'myMethod' có thể lấy hàm làm tham số; sau đó tại "gọi hàm", bạn gọi nó. Nhưng có rất nhiều kịch bản khác có thể xảy ra. Xem mã mẫu này để biết ví dụ: https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch24p842downloader/ch37p1099downloader/MyDownloader.swift – matt

3

Mở rộng về câu trả lời của Matt, bạn có thể làm myMethod một phương pháp mà phải mất một đóng cửa như một tham số:

​func​ ​myMethod​(​completionBlock​: (result: String) ->()) 
{ 
    // ... code ... 
    somebody.doSomethingWith(someObject, asynchronousCallback: { 
     (thing, otherThing) in 
     // ... do whatever 
     completionBlock(thing) 
    }) 
    // ... code ... 
} 
Các vấn đề liên quan