W dniu dzisiejszym najwięcej o współbieżności. Mamy API do kolejek wykonujących taski sekwencyjnie i równolegle (w tym z uwzględnieniem zależności). Forma wydaje się dość szkolna, nie ma takiego uproszczenia kodu jak w async, ale używający od razu wie, co robi. Zresztą w aplikacjach XAML też jawnie czasami musimy powiedzieć, w jakim wątku chcemy coś wykonać (nie wspominając o różnej obsłudze współbieżności w platformie .NET).
Współbieżność
Bloki
__block – zmienna modyfikowana w bloku
Kolejki Dispatch
Dwa typy
- Serial (jedno zadanie w danym czasie)
- możemy definiować własne
- wykonują kod w wątkach w tle
- Concurrent (wiele zadań równocześnie)
- dispatch_get_global_queue - referencja do kolejek
- cztery globalne kolejki w każdej aplikacji
- DISPATCH_QUEUE_PRIORITY_HIGH
- DISPATCH_QUEUE_PRIORITY_DEFAULT
- DISPATCH_QUEUE_PRIORITY_LOW
- DISPATCH_QUEUE_PRIORITY_BACKGROUND
- wykonywanie kodu w wątkach w tle
- liczba tasków wykonywanych równolegle jest zarządzana przez system
Dodawanie tasków do kolejki
dispatch_queue_t queue;
queue = dispatch_queue_create(“xxx”, DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
});
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
});
Kolejki Operation
?
- Nie FIFO, jak w Dispatch
- NSOperationQueue
- zawsze wykonują się równoległe
NSOperation
- opakowuje blok kodu do wykonania
- dodatkowe funkcjonalności
- - (void) addDependency: (NSOperation *) operation
- - (void) setCompletionBlock: (void(^)(void)) block
- - (void) setQueuePriority: (NSOperationQueuePriority) priority
- 2 podklasy
- NSInvocationOperation
- NSBlockOperation
- własne podklasy
- obserwacja klucz-wartość
- isCancelled
- isConcurrent
- isExecuting
- isFinished
- isReady
- dependencies
- queuePriority
- completionBlock
- zależności od innych operacji
- priorytet wykonania
- możliwość anulowania
- bloki Completed
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock: ^{
}];
[operation setQueuePriority: NSOperationQueuePriorityHigh];
[operation setThreadPriority: 0.5] //inny sposób określenia priorytetu
[operation setCompletionBlock: ^{
}];
[operation2 addDependency: operation];
[operation cancel];
[operation addObserver: self forKeyPath: @”isCancelled”
options: NSKeyValueObservingOptionNew
context: (__bridge void *) (zmienna)];
- (void) observeValueForKeyPath: (NSString *) keyPath
ofObject: (id) object change: (NSDictionary *) change
context: (void *) cotext {
}
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
[operationQueue addOperationWithBlock: ^{
//ten sam kod, co przy kolejkach Dispatch, w tym część kodu z wywołaniem w wątku UI
}];
[operationQueue addOperation: operation]; //dodanie NSBlockOperation
[operationQueue cancelAllOperations];
Tworzenie podklas NSOperation
[operation start] //bezpośrednie wywołanie operacji, domyślnie synchronicznie z wątkiem wołającym, nie równolegle
Operacje nierównoległe
- dziedziczą po NSOperation
- łatwiejsze do implementacji
- dodana do kolejki wykonuje się równolegle
- możliwość anulowania
@interface XOperation: NSOperation
@end
@implementation XOperation
- (void) main {
//praca
// sprawdzenie anulowania: [self isCancelled]
// praca
// w razie potrzeby powtórzenie
}
@end
Deploying
Od XCode 5 można z jego poziomu wygodnie tworzyć profile, identyfikatory, rejestrować urządzenia itd.
Profile
- developerski
- dystrybucyjny - ad hoc i do app store (certyfikaty do add hoc i app store mogą być te same)
.ipa to .zip (podobnie jak .xap czy .appx)
Debugowanie
Wyjątki i sygnały
di –s rejestr - odkodowanie informacji
NSSetUncaughtExceptionHandler / Signal handler - bardziej globalne przechwytywanie
AppDelegate:
NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
signal(SIGSEV, SignalHandler);
…
void UncaughtExceptionHandler(NSException *exception)
{
void* myCallStack[128];
int frames = backtrace(myCallStack, 128);
char **btstrings = backtrace_symbols(myCallStack, frames);
…
exception.name
exception.reason
exception.userInfo
}
void SignalHandler(int signal)
{
//ten sam kod wyciągania stosu
}
Device Logs
Rodzaje breakpointów
- General
- Logging
- Conditional
- Exception
- Symbolic (gdy jakaś funkcja / metoda zacznie się wykonywać)
- Executing
Brak komentarzy:
Prześlij komentarz