Upload
others
View
2
Download
0
Embed Size (px)
Citation preview
Blocks
• Mi az a block?
• Utasítások sorozata { }-ek között, amit egy objektumként tuduk kezelni.
• iOS 4.0 és Mac OSX 10.6 óta
!2
Blocks
• Egy példa a felépítésére [exampleDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {! NSLog(@"%@ : %@", key, value);! if ([key isEqualToString:@"stopKey"]) {! *stop = YES;! }!}]; !
• Minden block ^-vel kezdődik • Lehet visszatérési értéke • Lehetnek bemenő paraméterei (<#type#> <#name#>, ..) • { utasítások }
!3
Blocks• Lokális változók is használhatóak a block-on belül
int stopValue = 42; [exampleDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {! NSLog(@"%@ : %@", key, value);! if ([key isEqualToString:@“stopKey"] || [value intValue] == stopValue) {! *stop = YES;! }!}];
• DE! csak read-only !
__block BOOL stoppedEarly = NO;
int stopValue = 42; [exampleDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {! NSLog(@"%@ : %@", key, value);! if ([key isEqualToString:@“stopKey"] || [value intValue] == stopValue) {! stoppedEarly = YES; //HIBA *stop = YES;! }!}];
!5
Blocks
• Kivéve, ha ellátjuk egy __block storage type-al !__block int stopValue = 42; [exampleDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {! NSLog(@"%@ : %@", key, value);! if ([key isEqualToString:@“stopKey"] || [value intValue] == stopValue) {! stoppedEarly = YES; //Ebben az esetben már helyes *stop = YES;! }!}];
• Vagy, ha instance variable (_name) • De ezek elérésére a setter-eket és a getter-eket használjuk
!6
Blocks
• Mi van azokkal a változókkal, amiknek üzenetet küldünk? NSString *stopKey = @"stopKey";!__block BOOL stoppedEarly = NO;!int stopValue = 42;![exampleDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {! ! if ([stopKey isEqualToString:key] || ([value doubleValue] == stopValue)) {! *stop = YES;! stoppedEarly = YES;! }!}];!if (stoppedEarly) NSLog(@"I stopped logging dictionary values early!”);
• Ebben az esetben a stopKey a block lefutásáig automatikusan egy strong pointer lesz. Mert a block lefutásáig nem szabadulhet fel.
!7
Blocks
• Készítsünk egy olyan változót, amibe majd egy block-ot teszünk • Hogy bele tudjunk tenni egy változóba egy block-ot,
előbb meg kell határoznunk a változó típusát. • Szerkezet
typedef <#returnType#>(^<#name#>)(<#arguments#>); !
• Példa typedef double (^squareBlock)(double op);
!8
Blocks
• Készítsünk egy olyan változót, amibe majd egy block-ot teszünk
squareBlock square;!square = ^(double op) {! return op * op;!}; NSLog(@"square of five: %f", square(5)); !
• Nem kötelező a typedef, a következő módon is definiálhatunk egy block-ot double (^square)(double op) = ^(double op) { return op * op; }; NSLog(@"square of five: %f", square(5));
!9
Blocks
• Lecture 8 Slides.pdf / 21-28. dia
!10
Blocks
• Hol használunk block-okak? • Enumeration • View animations • Sorting • Notifications • Callbacks(Error handlers, Complition handlers) • Multithreading (GCD API)
!11
GCD
• Grand Central Dispatch • Dispatch queues are a C-based mechanism for
executing custom tasks • A dispatch queue executes tasks either serially or
concurrently but always in a first-in, first-out order • A serial dispatch queue runs only one task at a time,
waiting until that task is complete before dequeuing and starting a new one
• a concurrent dispatch queue starts as many tasks as it can without waiting for already started tasks to finish.
!12
GCD• Dispatch queues have other benefits:
• They provide a straightforward and simple programming interface. • They offer automatic and holistic thread pool management. • They provide the speed of tuned assembly. • They are much more memory efficient (because thread stacks do
not linger in application memory). • They do not trap to the kernel under load. • The asynchronous dispatching of tasks to a dispatch queue
cannot deadlock the queue. • They scale gracefully under contention. • Serial dispatch queues offer a more efficient alternative to locks
and other synchronization primitives.
!13
Operation Queues
• Egy operation queue a Cococa-s megfelelője a dispatch queue-nak
• NSOperationQueue osztály • Kibővíti a first-in, first-out rendezési elver (függőségek,
prioritás, KVO) • Egy operation queue-ba NSOperation példányokat
tehetünk • Az NSOperation egy abstract base class
!14
Operations
• Foundation framework-ben 3 típusú operationt találunk: NSInvocationOperation, NSBlockOperation, NSOperation
• NSInvocationOperation • Akkor hasznájuk, ha nagy számú egyedi operation-t
ugyanarra a feladatra használni NSInvocationOperation *theOp = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(myTaskMethod:) object:data]; !- (void)myTaskMethod:(id)data { // Perform the task. }
!15
Operations
• Foundation framework-ben 3 típusú operationt találunk: NSInvocationOperation, NSBlockOperation, NSOperation
• NSBlockOperation • Egy objektum orientált wrapper-t nyújt a dispatch
queue-ra NSBlockOperation *theOp = [NSBlockOperation blockOperationWithBlock: ^{
// Do some work. }];
!
!16
Operations• Foundation framework-ben 3 típusú operationt találunk:
NSInvocationOperation, NSBlockOperation, NSOperation • NSOperation
• Ha az NSInvocationOperation és a NSBlockOperation nem elégítik ki az igényeket, akkor az NSOperation-ből készítünk subclass-t
• Minden operation objektumnak meg kell valósítania a következő metódusokat • Custom initialization method • main
!17
Operations
@interface MyNonConcurrentOperation : NSOperation !@property (strong) id myData; !-(id)initWithData:(id)data; !@end !@implementation MyNonConcurrentOperation !- (id)initWithData:(id)data { if (self = [super init]) self.myData = data; return self; } !- (void)main { @try { // Do some work on myData and report the results. } @catch(...) { // Do not rethrow exceptions. } } !@end
!18
Nézzük meg a használatukat