2011-11-07 13 views
13

Bạn có thể sử dụng thông báo để liên lạc ngược lại chủ đề chính của ứng dụng IOS không? (cf performSelectorOnMainThread). Đó là, có bất kỳ gottcha cho mục đích này?có ổn không khi sử dụng thông báo để liên lạc ngược lại chủ đề chính của ứng dụng IOS? (cf performSelectorOnMainThread)

nền

  • muốn gọi trở lại thread UI chính từ một sợi nền (ví dụ performSelectorInBackground)
  • có thể sử dụng performSelectorOnMainThread để giao tiếp trở lại, nhưng tự hỏi nếu nó là OK để sử dụng một thông báo?

Ví dụ

[[NSNotificationCenter defaultCenter] postNotificationName:@"ModelChanged" object:self]; 

Trả lời

20

Thực tế có một gottcha; bạn sẽ sụp đổ ngẫu nhiên! Đó là kinh nghiệm của tôi. Điều này phải làm với thực tế là đối tượng nhận được thông báo thực hiện trên cùng một luồng với người gửi thông báo.

Từ Apple iOS Documentation on Notification Centers:

Trong một ứng dụng đa luồng, thông báo luôn giao trong thread trong đó thông báo đã được đăng, mà có thể không được như vậy chủ đề trong đó một người quan sát đăng ký chính nó.

Điều này chắc chắn sẽ khiến bạn đau đầu.

Nếu thông báo đang được nhận bởi một cái gì đó trên chủ đề chính, tôi đã tìm thấy rằng popping vào chủ đề chính từ chủ đề nền để phát hành một thông báo là cách an toàn nhất để đi về điều này. Nó là khá đơn giản để làm:

//Call this to post a notification and are on a background thread  
- (void) postmyNotification{ 
    [self performSelectorOnMainThread:@selector(helperMethod:) withObject:Nil waitUntilDone:NO]; 
} 

//Do not call this directly if you are running on a background thread. 
- (void) helperMethod{ 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"SOMENAME" object:self]; 
} 

Thật không may này giới thiệu một khớp nối tinh tế giữa người gửi và người nhận ở chỗ bạn đang thay đổi người gửi để thích ứng với người nhận.

Một giải pháp thậm chí tốt hơn, như XJones chỉ ra, là để người gửi gửi thông báo về bất kỳ chủ đề nào nó quyết định, và sau đó làm cho người nghe chịu trách nhiệm sử dụng chuỗi thích hợp để thực hiện bất kỳ hành động nào cần.

Hy vọng điều đó hữu ích.

+1

Tôi đã tham chiếu vấn đề này trong một bình luận trong câu trả lời của tôi. Tôi không thích giải pháp của bạn chính xác b/c của khớp nối giữa đối tượng đăng thông báo và người quan sát. Các đối tượng gửi bài nên đăng trên bất cứ chủ đề nó thích. Người nhận phải xử lý thông báo trên chuỗi mà nó cần (ví dụ: người nhận có thể chuyển tiếp thông báo đến chủ đề chính hoặc bất kỳ chủ đề nào khác). Apple cũng sử dụng phương pháp này trong mã mẫu của nó. – XJones

+0

Tôi hoàn toàn đồng ý. Tôi đã cập nhật câu trả lời của mình để phản ánh phương pháp này. – PixelCloudSt

+0

@PixelCloudSt Tôi hiểu các khớp nối trong phương pháp này, nhưng làm thế nào tôi sẽ đi về làm cho người nhận lắng nghe trên nhiều chủ đề? –

8

Yep, thông báo có thể được sử dụng cho mục đích này. bạn có thể sử dụng bất kỳ phương thức nào bạn thích (giao thức, thông báo, nhắn tin trực tiếp) để giao tiếp giữa các đối tượng trên các chuỗi. Cái nào bạn chọn tùy thuộc vào những gì bạn cảm thấy là thích hợp nhất. Thông báo là rất tốt khi đối tượng đăng thông báo không biết bất cứ điều gì về các đối tượng quan sát thông báo. Nếu bạn gửi thư (ví dụ: performSelectorOnMainThread) thì đối tượng gửi thư cần biết về đối tượng mà thư đang gửi thư đến (thường thông qua giao thức).

+0

ok cảm ơn - Tôi đã gặp một số sự cố (http://stackoverflow.com/questions/8032987/why-do-i-get-wait-fences-failed-to-receive-reply-for-this-code) và tự hỏi nếu điều này có thể là lý do – Greg

+1

ok, chỉ cần đăng một câu trả lời trên đó. Tôi thường tìm thấy nó tốt hơn để thực thi bất kỳ yêu cầu thread trong xử lý vs tại người gửi. Ví dụ, bạn có thể chắc chắn rằng bạn luôn luôn đăng thông báo trên các chủ đề chính nhưng điều này là tẻ nhạt. Các đối tượng gửi bài không nên quan tâm.Người nhận không quan tâm và nên chuyển tiếp thư đến chuỗi chính nếu thích hợp. – XJones

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