2011-02-07 26 views
9

Có thường là một ý tưởng hay khi gọi số -[NSRunLoop runUntilDate:]? Dường như nó hoạt động mà không có bất kỳ vấn đề nào, nhưng nó làm tôi lo lắng khi nói với vòng lặp chạy để chạy từ bên trong vòng lặp chạy.Đang gọi - [NSRunLoop runUntilDate:] một ý tưởng hay?

Thông tin khác:

Tôi có dự án đang tìm nạp dữ liệu từ dịch vụ REST. Một phần thông tin quan trọng cần thu được là phạm vi ngày có dữ liệu hợp lệ. Đó là một lượng dữ liệu rất nhỏ mà chỉ cần được nhận một lần, vì vậy tôi quyết định cách tốt nhất để xử lý nó là phải tải thuộc tính xuống dữ liệu nếu biến cục bộ là nil. Tôi đang sử dụng ASIHTTPRequestASINetworkQueue, vì vậy mọi thứ không đồng bộ theo mặc định và để làm việc này, thuộc tính này không thể trả lại cho đến khi dữ liệu được tải xuống và xử lý. Dưới đây là phác thảo mã của tôi, tên của các biến đã được thay đổi để bảo vệ người vô tội:

Một lần nữa, điều này có vẻ hoạt động tốt. Có bất kỳ vấn đề tiềm năng nào khi sử dụng phương pháp này không?

Trả lời

3

Bạn phải đảm bảo không thực hiện điều này từ bất kỳ phương thức nào có thể được gọi bằng vòng lặp chạy mà bạn đang gọi, trừ khi cây gọi chồng chéo hoàn toàn là người tham gia lại.

Mã giao diện người dùng Cocoa Touch không được ghi lại là người tham gia lại (trên thực tế, có cảnh báo/gợi ý từ Apple DTS), vì vậy nếu trình xử lý dữ liệu tìm nạp của bạn có thể được gọi bằng phương thức giao diện người dùng (hoặc mã không reentrant khác có thể được gọi trong vòng lặp chạy UI), gọi vòng lặp chạy UI từ bên trong nó không được khuyến khích.

+0

Vì vậy, trong trường hợp này, có vẻ như phương pháp này là an toàn vì không có gì khác mà có thể gọi thuộc tính này trong khi nó đang tải xuống dữ liệu. Nhưng nếu có một tình huống mà người dùng có thể nhấn một nút trong khi nó đang bận và gọi lại tài sản đó, thì nó sẽ nổ tung? Tốt để biết. –

+0

Tài sản này có được sử dụng trực tiếp hoặc gián tiếp bởi bất kỳ phương thức giao diện người dùng hoặc đại diện nào không? Nếu vậy, nó vẫn là một vấn đề lớn. – hotpaw2

+0

Tôi chắc chắn nó sẽ chỉ nhấn mã này một lần khi ứng dụng tải ban đầu trước khi giao diện người dùng được trình bày cho người dùng. Sau đó, dữ liệu sẽ ở đó và nó sẽ sử dụng biến cục bộ. Nếu nó không thể tải xuống dữ liệu vì một lý do nào đó, nó sẽ hiển thị cảnh báo phương thức cho người dùng và họ không thể truy cập vào ứng dụng cho đến khi tải xuống thành công. –

4

Không tốt hơn để hiển thị một số loại spinner và xé nó xuống để đáp ứng với các sự kiện hoàn thành không đồng bộ từ mã mạng? Giống như:

[self displayLoadingSpinner]; 
[request setCompletionBlock:^{ 
    [self handleSuccess]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self hideLoadingSpinner]; 
    }]; 
}]; 
[request setFailedBlock:^{ 
    [self handleFailure]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self hideLoadingSpinner]; 
    }]; 
}]; 
[queue addOperation:request]; 

Tôi sẽ xem xét điều này tốt hơn khỉ với vòng lặp chạy. Nhưng nó có thể là bạn đã biết điều này và chỉ muốn biết những hạn chế chính xác là có trong các giải pháp runloop?


Nếu bạn muốn chặn đến khi giá trị sẵn sàng, bạn có thể sử dụng một semaphore:

dispatch_semaphore_t sem = dispatch_semaphore_create(0); 
[request setCompletionBlock:^{ 
    dispatch_semaphore_signal(sem); 
}]; 
[queue addOperation:request]; 

dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); 
dispatch_release(sem); 
+0

Đây là phương pháp tôi sẽ thực hiện nếu phương pháp tiếp cận phương thức đại biểu/gọi lại là có thể. Trong trường hợp này, tôi cần giá trị được đặt trước khi tôi quay trở lại từ thuộc tính hoặc ứng dụng khác sẽ tiếp tục với dữ liệu không hợp lệ. Tôi có thể cấu trúc lại mã để mẫu thiết kế có thể hoạt động. Câu hỏi này thực sự là tìm ra nếu có thể có bất kỳ vấn đề bất ngờ với cách tiếp cận của tôi mà tôi chỉ chưa thấy. –

+0

Cách tiếp cận semaphore sẽ không chặn luồng chính? Điều đó sẽ không ngăn chặn các khối thực thi? –

+0

Tùy thuộc vào cách thư viện HTTP bạn sử dụng được triển khai.Có, chủ đề chính sẽ chặn, để nếu thư viện sử dụng chủ đề chính, bạn không thể sử dụng semaphore. – zoul

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