2013-02-24 15 views
12

Jestem nowy w stosunku do celu C, pochodzącego z tła .NET i java.Tworzenie widoku na wątku tła, dodając go do głównego widoku głównego wątku.

Więc muszę utworzyć kilka UIwebviews asynchronicznie, robię to na moim własnym kolejce wykorzystaniem

 dispatch_queue_t queue = dispatch_queue_create("myqueue", NULL); 
    dispatch_async(queue, ^{ 
     // create UIwebview, other things too 
      [self.view addSubview:webView]; 
     }); 

jak owuld sobie wyobrazić to zgłasza błąd:

bool _WebTryThreadLock(bool), 0xa1b8d70: Tried to obtain the web lock from a thread other 
    than the main thread or the web thread. This may be a result of calling to UIKit from a 
    secondary thread. Crashing now... 

Więc jak mogę dodać Wywiad na głównym wątku?

Odpowiedz

16

Skoro już używasz kolejki wysyłki. Nie używałbym performSelectorOnMainThread:withObject:waitUntilDone:, ale raczej wykonuję dodatek do podglądu w głównej kolejce.

dispatch_queue_t queue = dispatch_queue_create("myqueue", NULL); 
dispatch_async(queue, ^{ 
    // create UIwebview, other things too 

    // Perform on main thread/queue 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self.view addSubview:webView]; 
    }); 
}); 

Jest dobrze, aby instancję UIWebView w kolejce tła. Ale aby dodać go jako podgląd, musisz być w głównym wątku/kolejce. Z dokumentacji UIView:

gwintów Rozważania

manipulacje na interfejsie użytkownika danej aplikacji musi pojawić się na głównym wątku. Dlatego należy zawsze wywoływać metody klasy UIView z kodu działającego w głównym wątku aplikacji. Jedyny czas, który może nie być absolutnie konieczny, to tworzenie samego obiektu widoku, ale wszystkie inne manipulacje powinny wystąpić w głównym wątku.

+0

uwaga, nawet initWithFrame nie gwarantuje bezpieczeństwa wątku. zobacz http://stackoverflow.com/questions/11122957/is-it-ok-to-create-a-uiview-on-a-background-thread – stefreak

+0

Może moje zrozumienie "wątku bezpiecznego" jest złe. Ale myślę, że bezpieczne dla wątków oznacza, że ​​obiekt może być manipulowany z kilku wątków jednocześnie. Na przykład. można by pomyśleć o macierzy bezpiecznej dla wątków, która pozwalałaby dodawać obiekty z wielu wątków. Jednak w tym przypadku nie manipulujemy ani nie uzyskujemy dostępu do obiektu widoku z wielu wątków/kolejek jednocześnie. Tworzymy go w jednym wątku/kolejce, a następnie przekazujemy go do innego. – Florian

+0

Okazuje się, że odpowiedź na pytanie, które łączyłem, była myląca - przepraszam. Apple mówi: "Jedyny czas, który może nie być absolutnie konieczny, to tworzenie samego obiektu widoku", więc powinno być bezpieczne. – stefreak

2

Większość obiektów UIKit, w tym instancje UIView, należy zmanipulować tylko z głównego wątku/kolejki. Nie można wysyłać wiadomości do urządzenia UIView w żadnym innym wątku lub kolejce. Oznacza to również, że nie można ich utworzyć w żadnym innym wątku lub kolejce.

+5

To nie do końca poprawne. Całkiem dobrze jest utworzyć widok w tle. Z dokumentacji UIView: Manipulacje do interfejsu użytkownika aplikacji muszą wystąpić w głównym wątku. Dlatego należy zawsze wywoływać metody klasy UIView z kodu działającego w głównym wątku aplikacji. Jedyny czas, który może nie być absolutnie konieczny, to tworzenie samego obiektu widoku, ale wszystkie inne manipulacje powinny wystąpić w głównym wątku. – Florian

+0

@Florian Czy można użyć metody addSubview w tle, jeśli oba widoki nie wchodzą w interakcje z interfejsem użytkownika? –

+0

@BohdanSavych Nie jestem tego pewien. Jaki jest twój przypadek użycia? – Florian

1

Jako Rob powiedział, że zmiany UI powinny być wykonywane tylko na głównej thread.You próbują dodać od wtórnego thread.Change kod [self.view addSubview:webView]; do

[self.view performSelectorOnMainThread:@selector(addSubview:) withObject:webView waitUntilDone:YES];

Powiązane problemy