Objective-C Блоки (Block)<br />
Типилитерал блока<br />typedefint (^MyBlock)(int);<br />intmultiplier = 7;<br />MyBlockmyBlock = ^(intnum) {<br />returnnu...
Вызов блока<br />{<br />...<br />myBlock( 3);<br />//или<br />if ( myBlock )<br />myBlock( 3 );<br />}<br />Результат: 21<...
Контекст блока1. примитивные типы<br />int multiplier = 7;<br />int(^myBlock)(int) = ^(intnum) {<br />return num * multipl...
Контекст блока2. ключевое слово __block<br />__blockint multiplier = 7;<br />int(^myBlock)(int) = ^(intnum) {<br />return ...
Контекст блока3. переменные – указатели на объекты с подсчетом ссылок (id, NSObject)<br />NSDate* date = [ [ NSDate alloc ...
Контекст блока4a. управление памятью<br />NSDate* date = [ [ NSDate alloc ] init ];<br />//создаем блок в стеке<br />void(...
Контекст блока4b. управление памятью<br />__blockNSDate* date = [ [ NSDatealloc ] init ];<br />void(^printDate)() = ^() {<...
Блоки и управление памятью1. отложенный вызов<br />void (^printDate)() = ^() {<br />NSLog( @”Hello”);<br /> };<br />//доб...
Блоки и управление памятью2. block как результат функции<br />-(JFFSimpleBlock)example<br />{<br />return [ [ ^<br />   {<...
Блоки и управление памятью3. Виды блоковых объектов<br />Глобальные- без состояния<br />Локальные- в стеке<br />Malloc- Бл...
Управление памятью и Блоки<br />
Automatic Reference CountingNocopy, release and autorelease<br />
БлокиBest practice<br />1. Работа с контейнерами на примере NSArray<br />2. Охраняющиевыражения -guards<br />3. Отложенные...
NSArrayconcurrent enumerate<br />NSArray* arr_ = [ NSArrayarrayWithObjects: @"1"<br />, @"2”<br />                   , @"3...
NSArrayСтрогая типизация vsNSPredicate<br />NSArray* array_ = [ NSArrayarrayWithObjects: @"1"<br />                      ,...
JFFLibrirary’sNSArrayрасширенияJFFLibrirarygithub<br />+(id)arrayWithSize:( NSUInteger )size_<br />          producer:( Pr...
Охраняющиевыражения–guards<br />{<br />  [ selfbeginUpdates ];<br />   //update rows here<br />//здесь ошибка если conditi...
Охраняющиевыражения –guards<br />-(void)withinUpdates:( void (^)( void ) )block_<br />{<br />   [ selfbeginUpdates ];<br /...
Охраняющиевыражения –guards<br />{<br />   [ self.tableViewwithinUpdates: ^( void )<br />   {<br />//updaterowshere<br />i...
Отложенные вызовыonDeallocBlocks<br />-(void)dealloc<br />{<br />   [ [ NSNotificationCenterdefaultCenter ] removeObserver...
Отложенные вызовыonDeallocBlocks<br />1. objc_setAssociatedObject( self<br />, &ownerships_key_<br />, ownerships_<br />, ...
Отложенные вызовыonDeallocBlocks<br />-(void)addOnDeallocBlock:( void(^)( void ) )block_<br />{<br />JFFOnDeallocBlockOwne...
Отложенные вызовыonDeallocBlocks<br /> //лечим циклическую ссылку<br />__blockid self_ = self;<br />[ selfaddOnDeallocBloc...
Отложенные вызовыScheduled operations<br /> [ selfperformSelector: @selector( someMethod )<br />withObject: nil<br />after...
Отложенные вызовыScheduled operations<br />__blockid self_ = self;<br />JFFScheduledBlockbk_= ^<br />{<br /> [ self_ someM...
Блоки вместо делегатов в UIAlertView<br />-(void)alertView:( UIAlertView* )alert_view_ clickedButtonAtIndex:( NSInteger )b...
Блоки вместо делегатов в UIAlertView<br />JFFAlertButton* bt_ = [ JFFAlertButtonalertButton: title_<br />action: ^<br />{<...
Обобщенное асинхронное программирование<br />1. Асинхронная операция в общем виде<br />2. Кеширование<br />3. Порядок выпо...
Асинхронная операция в общем виде<br />CancelBlock(^AsyncOperation)<br />         ( ProgressHandler<br />, CancelHandler<b...
Кеширование<br />Логический запрос 1<br />Логический запрос 2<br />Физическийзапрос<br />Ответ 1<br />Ответ 2<br />
Кэширование,API<br />//физическийзапрос<br />JFFAsyncOperationdata_loader_ = ...;<br />//кэшированный запрос<br />JFFAsync...
Порядоквыполнения -последовательность<br />sequence_ = sequenceOfAsyncOperations( operation1_<br />                 , oper...
Порядоквыполнения -группа<br />group_ = groupOfAsyncOperations( operation1_<br />                  , operation2_<br />			,...
Порядоквыполнения –графленивыевычисления<br />JFFAsyncOperationother_pages_ = ^( callbacks_ )<br />{<br />NSArray* loaders...
Loadbalancer<br />//имя текущего контекста<br />voidsetBalancerActiveContextName( NSString* name_ );<br />//сбалансированн...
Запросы и сессия<br />safe_loader_ =checkSessionForLoaderBlock( loader_ )<br />Login<br />Logout<br />
Легкий делегат<br />{<br />   [ self.clipasyncImageWithWeakDelegate: self ];<br />}<br />#pragma mark ClipDelegate<br /> -...
Легкий делегат<br />JFFAsyncOperationloader_ = …;<br />__blockidweak_delegate_ = delegate_;<br />[ weak_delegate_ weakAsyn...
Легкий делегат ARC<br />JFFAsyncOperation loader_ = …;<br />weak idweak_delegate_ = delegate_;<br />loader_( nil<br />, ni...
Всем спасибо !!!<br />Email:gorbenko.vova@gmail.com<br />Skype: vova.gorbenko.mac<br />
Upcoming SlideShare
Loading in …5
×

Владимир Горбенко «Использование блоков в Objective-C»

6,281 views

Published on

Published in: Technology, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
6,281
On SlideShare
0
From Embeds
0
Number of Embeds
3,253
Actions
Shares
0
Downloads
15
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • Еще сложнее если два алерта
  • Владимир Горбенко «Использование блоков в Objective-C»

    1. 1. Objective-C Блоки (Block)<br />
    2. 2. Типилитерал блока<br />typedefint (^MyBlock)(int);<br />intmultiplier = 7;<br />MyBlockmyBlock = ^(intnum) {<br />returnnum * multiplier;<br />};<br />ИЛИ<br />intmultiplier = 7;<br />int(^myBlock)(int) = ^(intnum) {<br />return num * multiplier;<br />};<br />
    3. 3. Вызов блока<br />{<br />...<br />myBlock( 3);<br />//или<br />if ( myBlock )<br />myBlock( 3 );<br />}<br />Результат: 21<br />
    4. 4. Контекст блока1. примитивные типы<br />int multiplier = 7;<br />int(^myBlock)(int) = ^(intnum) {<br />return num * multiplier;<br />};<br />multiplier = 8;<br />NSLog( @"%d", myBlock( 3 ) );<br />Печатает: 21<br />
    5. 5. Контекст блока2. ключевое слово __block<br />__blockint multiplier = 7;<br />int(^myBlock)(int) = ^(intnum) {<br />return num * multiplier;<br />};<br /> multiplier = 8;<br />NSLog( @"%d", myBlock( 3 ) );<br />Печатает:24<br />
    6. 6. Контекст блока3. переменные – указатели на объекты с подсчетом ссылок (id, NSObject)<br />NSDate* date = [ [ NSDate alloc ] init ];<br />void(^printDate)() = ^() {<br />NSLog( @"date: %@", date );<br />};<br />//копируем блок в кучу<br />printDate = [ [ printDatecopy ] autorelease ];<br />[ date release ];<br />printDate();<br />
    7. 7. Контекст блока4a. управление памятью<br />NSDate* date = [ [ NSDate alloc ] init ];<br />//создаем блок в стеке<br />void(^printDate)() = ^() {<br />NSLog( @"date: %@", date );<br />};<br />[ date release ];<br />//копируем блок в кучу и падаем<br />printDate = [ [ printDatecopy ] autorelease ];<br />
    8. 8. Контекст блока4b. управление памятью<br />__blockNSDate* date = [ [ NSDatealloc ] init ];<br />void(^printDate)() = ^() {<br />//здесь падаем при обращении к date<br />NSLog( @"date: %@", date );<br />};<br />//копируем блок в кучу, для объекта dateretain не вызывается<br />printDate= [ [ printDatecopy ] autorelease ];<br />[ date release ];<br />printDate();<br />
    9. 9. Блоки и управление памятью1. отложенный вызов<br />void (^printDate)() = ^() {<br />NSLog( @”Hello”);<br /> };<br />//добавление в контейнер<br />printDate = [ [ printDatecopy ] autorelease ];<br />[ NSMutableArrayarrayWithObject: printDate];<br />self.simpleBlock = printDate;<br />//всегда копируем block property<br />@property( copy ) JFFSimpleBlocksimpleBlock;<br />
    10. 10. Блоки и управление памятью2. block как результат функции<br />-(JFFSimpleBlock)example<br />{<br />return [ [ ^<br /> {<br />NSLog( @"test" );<br /> } copy ] autorelease ];<br />}<br />
    11. 11. Блоки и управление памятью3. Виды блоковых объектов<br />Глобальные- без состояния<br />Локальные- в стеке<br />Malloc- Блоки в куче<br />Ios < 4.0 support:<br />PLBlocks- googlecode<br />ESBlocksRuntime–github<br />
    12. 12. Управление памятью и Блоки<br />
    13. 13. Automatic Reference CountingNocopy, release and autorelease<br />
    14. 14. БлокиBest practice<br />1. Работа с контейнерами на примере NSArray<br />2. Охраняющиевыражения -guards<br />3. Отложенные вызовы:<br />onDeallocBlock<br />Scheduled operations<br />4. Блоки вместо делегатов в UIAlertView<br />
    15. 15. NSArrayconcurrent enumerate<br />NSArray* arr_ = [ NSArrayarrayWithObjects: @"1"<br />, @"2”<br /> , @"3”<br />, nil ];<br />[arr_ enumerateObjectsWithOptions: NSEnumerationConcurrent<br />usingBlock: ^( idobj_<br /> , NSUIntegeridx_<br />, BOOL* stop_)<br />{<br />NSLog( @"start process: %@", obj_ );<br />sleep( 4 );<br />NSLog( @"stop process: %@", obj_ );<br />} ];<br />
    16. 16. NSArrayСтрогая типизация vsNSPredicate<br />NSArray* array_ = [ NSArrayarrayWithObjects: @"1"<br /> , @"2"<br /> , @"3"<br /> , nil ];<br />[ array_ indexOfObjectPassingTest: ^( idobj_<br /> , NSUIntegeridx_<br /> , BOOL* stop_)<br />{<br />NSString* element_ = obj_;<br />return[ element_ isEqualToString: @"2" ];<br />} ];<br />
    17. 17. JFFLibrirary’sNSArrayрасширенияJFFLibrirarygithub<br />+(id)arrayWithSize:( NSUInteger )size_<br /> producer:( ProducerBlock )block_;<br />-(void)each:( ActionBlock )block_;<br />-(NSArray*)map:( MappingBlock )block_;<br />-(NSArray*)select:( PredicateBlock )predicate_;<br />-(NSArray*)flatten:( FlattenBlock )block_;<br />-(NSUInteger)count:( PredicateBlock )predicate_;<br />-(id)firstMatch:( PredicateBlock )predicate_;<br />-(void)transformWithArray:( NSArray* )other_<br />withBlock:( TransformBlock )block_;<br />
    18. 18. Охраняющиевыражения–guards<br />{<br /> [ selfbeginUpdates ];<br /> //update rows here<br />//здесь ошибка если condition_ == true, мы не вызовем endUpdates<br /> if( condition_ )<br />return;<br /> //update rows here<br /> [ selfendUpdates ];<br />}<br />
    19. 19. Охраняющиевыражения –guards<br />-(void)withinUpdates:( void (^)( void ) )block_<br />{<br /> [ selfbeginUpdates ];<br />@try<br /> {<br />block_();<br /> }<br />@finally<br /> {<br /> [ selfendUpdates ];<br /> }<br />}<br />
    20. 20. Охраняющиевыражения –guards<br />{<br /> [ self.tableViewwithinUpdates: ^( void )<br /> {<br />//updaterowshere<br />if ( condition_ )<br />return;<br />//updaterowshere<br /> } ];<br />}<br />
    21. 21. Отложенные вызовыonDeallocBlocks<br />-(void)dealloc<br />{<br /> [ [ NSNotificationCenterdefaultCenter ] removeObserver: self ];<br />//release ivarshere if NO ARC<br /> [ superdealloc ];<br />}<br />ИЛИ<br />-(void)dealloc<br />{<br /> [ selfcancelSomeOperations ];<br />//release ivarshere if NO ARC<br /> [ superdealloc ];<br />}<br />
    22. 22. Отложенные вызовыonDeallocBlocks<br />1. objc_setAssociatedObject( self<br />, &ownerships_key_<br />, ownerships_<br />, RETAIN_NONATOMIC);<br />2. Class JFFOnDeallocBlockOwner<br />-(void)dealloc<br />{<br />if ( _block )<br /> {<br />_block();<br /> [ _blockrelease ];<br /> }<br /> [ superdealloc ];<br />}<br />
    23. 23. Отложенные вызовыonDeallocBlocks<br />-(void)addOnDeallocBlock:( void(^)( void ) )block_<br />{<br />JFFOnDeallocBlockOwner* owner_ = <br />[ [ JFFOnDeallocBlockOwneralloc] initWithBlock: <br />block_ ];<br />[ self.ownershipsaddObject: owner_ ];<br />[ owner_ release ];<br />}<br />
    24. 24. Отложенные вызовыonDeallocBlocks<br /> //лечим циклическую ссылку<br />__blockid self_ = self;<br />[ selfaddOnDeallocBlock: ^<br />{<br />[ [ NSNotificationCenterdefaultCenter ] removeObserver: self_ ];<br />} ];<br />
    25. 25. Отложенные вызовыScheduled operations<br /> [ selfperformSelector: @selector( someMethod )<br />withObject: nil<br />afterDelay: 20. ];<br />[ NSObjectcancelPreviousPerformRequestsWithTarget: self ];//отмена<br />ИЛИ<br />[ NSTimerscheduledTimerWithTimeInterval: 20.<br />target: self<br />selector: @selector( someMethod )<br />userInfo: nil<br />repeats: YES ];<br /> [ timer_ invalidate ]; //отмена<br />
    26. 26. Отложенные вызовыScheduled operations<br />__blockid self_ = self;<br />JFFScheduledBlockbk_= ^<br />{<br /> [ self_ someMethod ];<br />}<br />CancelBlockcancel_ = [ JFFScheduleraddBlock: bk_<br />duration: 20. ];<br /> [ selfaddOnDeallocBlock: cancel_ ];<br />
    27. 27. Блоки вместо делегатов в UIAlertView<br />-(void)alertView:( UIAlertView* )alert_view_ clickedButtonAtIndex:( NSInteger )button_index_<br />{<br />NSString* title_ = [ alert_view_ buttonTitleAtIndex: button_index_ ];<br />if( [title_ isEqualToString: cancel_ ] )<br />//..<br />elseif ( [ title_ isEqualToString: button1_ ] )<br />//..<br />elseif ( [ title_ isEqualToString: button2_ ] )<br />//..<br />}<br />
    28. 28. Блоки вместо делегатов в UIAlertView<br />JFFAlertButton* bt_ = [ JFFAlertButtonalertButton: title_<br />action: ^<br />{<br />//do some action<br />} ];<br />JFFAlertView* alert_view_ =<br />[ JFFAlertViewalertWithTitle: @"Alert2"<br />message: @"test"<br />cancelButtonTitle: @"Cancel"<br />otherButtonTitles: bt_, nil ];<br />
    29. 29. Обобщенное асинхронное программирование<br />1. Асинхронная операция в общем виде<br />2. Кеширование<br />3. Порядок выполнения<br />Дерево зависимостей, login<br />Lazy load, вычитка страниц<br />4.Load balancer<br />5. Асинхронные операции в контексте сессии<br />6. Асинхронные операции в UI<br />
    30. 30. Асинхронная операция в общем виде<br />CancelBlock(^AsyncOperation)<br /> ( ProgressHandler<br />, CancelHandler<br /> , FinishHandler) { … };<br />
    31. 31. Кеширование<br />Логический запрос 1<br />Логический запрос 2<br />Физическийзапрос<br />Ответ 1<br />Ответ 2<br />
    32. 32. Кэширование,API<br />//физическийзапрос<br />JFFAsyncOperationdata_loader_ = ...;<br />//кэшированный запрос<br />JFFAsyncOperationcached_loader_ =<br />[ selfasyncOperationForPropertyWithName: @”image”<br />asyncOperation: data_loader_ ];<br />
    33. 33. Порядоквыполнения -последовательность<br />sequence_ = sequenceOfAsyncOperations( operation1_<br /> , operation2_<br /> , nil );<br />Асинхронная операция как последовательность<br />…<br />Асин. оп.1<br />Асин. оп.2<br />Асин. Оп.N<br />
    34. 34. Порядоквыполнения -группа<br />group_ = groupOfAsyncOperations( operation1_<br /> , operation2_<br /> , nil );<br />Запрос 1<br />Запрос 2<br />Запрос 3<br />Группа запросов<br />
    35. 35. Порядоквыполнения –графленивыевычисления<br />JFFAsyncOperationother_pages_ = ^( callbacks_ )<br />{<br />NSArray* loaders_ = …;<br /> result_ = groupOfAsyncOp( loaders_ );<br />returnresult_( callbacks_ );<br />};<br />sequenceOfAsyncOperations( first_page_<br /> , other_pages_<br /> , nil );<br />
    36. 36. Loadbalancer<br />//имя текущего контекста<br />voidsetBalancerActiveContextName( NSString* name_ );<br />//сбалансированная асинхронная операция<br />balanced_loader_ = balancedAsyncOperation( loader_ );<br />
    37. 37. Запросы и сессия<br />safe_loader_ =checkSessionForLoaderBlock( loader_ )<br />Login<br />Logout<br />
    38. 38. Легкий делегат<br />{<br /> [ self.clipasyncImageWithWeakDelegate: self ];<br />}<br />#pragma mark ClipDelegate<br /> -(void)clip:( Clip* )clip_<br />didLoadImage:( UIImage* )image_<br />error:( NSError* )error_<br />{<br />if ( self.clip!= clip_ )<br />return;<br />self.imageView.image= image_;<br />}<br />
    39. 39. Легкий делегат<br />JFFAsyncOperationloader_ = …;<br />__blockidweak_delegate_ = delegate_;<br />[ weak_delegate_ weakAsyncOperation: loader_ ]<br />( nil, nil, ^( idimage_, NSError* error_ )<br />{<br />[ weak_delegate_ clip: self<br />didLoadImage: image_<br />error: error_ ];<br />} );<br />
    40. 40. Легкий делегат ARC<br />JFFAsyncOperation loader_ = …;<br />weak idweak_delegate_ = delegate_;<br />loader_( nil<br />, nil<br />, ^( idimage_<br />, NSError* error_ )<br /> {<br /> [ weak_delegate_ clip: self<br />didLoadImage: image_<br />error: error_ ];<br /> } );<br />
    41. 41. Всем спасибо !!!<br />Email:gorbenko.vova@gmail.com<br />Skype: vova.gorbenko.mac<br />

    ×