Objective-C Блоки (Block)

Содержание

Слайд 2

Тип и литерал блока

typedef int (^MyBlock)(int);
int multiplier = 7;
MyBlock myBlock =

Тип и литерал блока typedef int (^MyBlock)(int); int multiplier = 7; MyBlock
^(int num) {
return num * multiplier;
};
ИЛИ
int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
return num * multiplier;
};

Слайд 3

Вызов блока

{
...
myBlock( 3 );
//или
if ( myBlock )
myBlock(

Вызов блока { ... myBlock( 3 ); //или if ( myBlock )
3 );
}
Результат: 21

Слайд 4

Контекст блока 1. примитивные типы

int multiplier = 7;
int (^myBlock)(int) = ^(int

Контекст блока 1. примитивные типы int multiplier = 7; int (^myBlock)(int) =
num) {
return num * multiplier;
};
multiplier = 8;
NSLog( @"%d", myBlock( 3 ) );
Печатает: 21

Слайд 5

Контекст блока 2. ключевое слово __block

__block int multiplier = 7;
int (^myBlock)(int) =

Контекст блока 2. ключевое слово __block __block int multiplier = 7; int
^(int num) {
return num * multiplier;
};
multiplier = 8;
NSLog( @"%d", myBlock( 3 ) );
Печатает: 24

Слайд 6

Контекст блока 3. переменные – указатели на объекты с подсчетом ссылок (id, NSObject)

Контекст блока 3. переменные – указатели на объекты с подсчетом ссылок (id,

NSDate* date = [ [ NSDate alloc ] init ];
void (^printDate)() = ^() {
NSLog( @"date: %@", date );
};
//копируем блок в кучу
printDate = [ [ printDate copy ] autorelease ];
[ date release ];
printDate();

Слайд 7

Контекст блока 4a. управление памятью


NSDate* date = [ [ NSDate alloc

Контекст блока 4a. управление памятью NSDate* date = [ [ NSDate alloc
] init ];
//создаем блок в стеке
void (^printDate)() = ^() {
NSLog( @"date: %@", date );
};
[ date release ];
//копируем блок в кучу и падаем
printDate = [ [ printDate copy ] autorelease ];

Слайд 8

Контекст блока 4b. управление памятью
__block NSDate* date = [ [ NSDate alloc ]

Контекст блока 4b. управление памятью __block NSDate* date = [ [ NSDate
init ];
void (^printDate)() = ^() {
//здесь падаем при обращении к date
NSLog( @"date: %@", date );
};
//копируем блок в кучу, для объекта date retain не вызывается
printDate = [ [ printDate copy ] autorelease ];
[ date release ];
printDate();

Слайд 9

Блоки и управление памятью 1. отложенный вызов

void (^printDate)() = ^() {
NSLog( @”Hello

Блоки и управление памятью 1. отложенный вызов void (^printDate)() = ^() {
☺” );
};
//добавление в контейнер
printDate = [ [ printDate copy ] autorelease ];
[ NSMutableArray arrayWithObject: printDate ];
self.simpleBlock = printDate;
//всегда копируем block property
@property ( copy ) JFFSimpleBlock simpleBlock;

Слайд 10

Блоки и управление памятью 2. block как результат функции

-(JFFSimpleBlock)example
{
return [ [ ^

Блоки и управление памятью 2. block как результат функции -(JFFSimpleBlock)example { return
{
NSLog( @"test" );
} copy ] autorelease ];
}

Слайд 11

Блоки и управление памятью 3. Виды блоковых объектов

Глобальные - без состояния
Локальные - в

Блоки и управление памятью 3. Виды блоковых объектов Глобальные - без состояния
стеке
Malloc - Блоки в куче
Ios < 4.0 support:
PLBlocks - googlecode
ESBlocksRuntime – github

Слайд 12

Управление памятью и Блоки

Управление памятью и Блоки

Слайд 13

Automatic Reference Counting No copy, release and autorelease

Automatic Reference Counting No copy, release and autorelease

Слайд 14

Блоки Best practice
1. Работа с контейнерами на примере NSArray
2. Охраняющие выражения - guards
3.

Блоки Best practice 1. Работа с контейнерами на примере NSArray 2. Охраняющие
Отложенные вызовы:
onDeallocBlock
Scheduled operations
4. Блоки вместо делегатов в UIAlertView

Слайд 15

NSArray concurrent enumerate

NSArray* arr_ = [ NSArray arrayWithObjects: @"1"
, @"2”
,

NSArray concurrent enumerate NSArray* arr_ = [ NSArray arrayWithObjects: @"1" , @"2”
@"3”
, nil ];
[arr_ enumerateObjectsWithOptions: NSEnumerationConcurrent
usingBlock: ^( id obj_
, NSUInteger idx_
, BOOL* stop_)
{
NSLog( @"start process: %@", obj_ );
sleep( 4 );
NSLog( @"stop process: %@", obj_ );
} ];

Слайд 16

NSArray Строгая типизация vs NSPredicate

NSArray* array_ = [ NSArray arrayWithObjects: @"1"

NSArray Строгая типизация vs NSPredicate NSArray* array_ = [ NSArray arrayWithObjects: @"1"
, @"2"
, @"3"
, nil ];
[ array_ indexOfObjectPassingTest: ^( id obj_
, NSUInteger idx_
, BOOL* stop_)
{
NSString* element_ = obj_;
return [ element_ isEqualToString: @"2" ];
} ];

Слайд 17

JFFLibrirary’s NSArray расширения JFFLibrirary github
+(id)arrayWithSize:( NSUInteger )size_
producer:( ProducerBlock )block_;
-(void)each:( ActionBlock )block_;
-(NSArray*)map:( MappingBlock

JFFLibrirary’s NSArray расширения JFFLibrirary github +(id)arrayWithSize:( NSUInteger )size_ producer:( ProducerBlock )block_; -(void)each:(
)block_;
-(NSArray*)select:( PredicateBlock )predicate_;
-(NSArray*)flatten:( FlattenBlock )block_;
-(NSUInteger)count:( PredicateBlock )predicate_;
-(id)firstMatch:( PredicateBlock )predicate_;
-(void)transformWithArray:( NSArray* )other_
withBlock:( TransformBlock )block_;

Слайд 18

Охраняющие выражения – guards

{
[ self beginUpdates ];
//update rows here
//здесь

Охраняющие выражения – guards { [ self beginUpdates ]; //update rows here
ошибка если condition_ == true, мы не вызовем endUpdates
if ( condition_ )
return;
//update rows here
[ self endUpdates ];
}

Слайд 19

Охраняющие выражения – guards

-(void)withinUpdates:( void (^)( void ) )block_
{
[ self beginUpdates

Охраняющие выражения – guards -(void)withinUpdates:( void (^)( void ) )block_ { [
];
@try
{
block_();
}
@finally
{
[ self endUpdates ];
}
}

Слайд 20

Охраняющие выражения – guards
{
[ self.tableView withinUpdates: ^( void )
{
//update

Охраняющие выражения – guards { [ self.tableView withinUpdates: ^( void ) {
rows here
if ( condition_ )
return;
//update rows here
} ];
}

Слайд 21

Отложенные вызовы onDeallocBlocks

-(void)dealloc
{
[ [ NSNotificationCenter defaultCenter ] removeObserver: self ];
//release ivars

Отложенные вызовы onDeallocBlocks -(void)dealloc { [ [ NSNotificationCenter defaultCenter ] removeObserver: self
here if NO ARC
[ super dealloc ];
}
ИЛИ
-(void)dealloc
{
[ self cancelSomeOperations ];
//release ivars here if NO ARC
[ super dealloc ];
}

Слайд 22

Отложенные вызовы onDeallocBlocks

1. objc_setAssociatedObject( self
, &ownerships_key_
, ownerships_
, RETAIN_NONATOMIC );
2. Class

Отложенные вызовы onDeallocBlocks 1. objc_setAssociatedObject( self , &ownerships_key_ , ownerships_ , RETAIN_NONATOMIC
JFFOnDeallocBlockOwner
-(void)dealloc
{
if ( _block )
{
_block();
[ _block release ];
}
[ super dealloc ];
}

Слайд 23

Отложенные вызовы onDeallocBlocks

-(void)addOnDeallocBlock:( void(^)( void ) )block_
{
JFFOnDeallocBlockOwner* owner_ =
[ [

Отложенные вызовы onDeallocBlocks -(void)addOnDeallocBlock:( void(^)( void ) )block_ { JFFOnDeallocBlockOwner* owner_ =
JFFOnDeallocBlockOwner alloc ] initWithBlock:
block_ ];
[ self.ownerships addObject: owner_ ];
[ owner_ release ];
}

Слайд 24

Отложенные вызовы onDeallocBlocks
//лечим циклическую ссылку
__block id self_ = self;
[ self

Отложенные вызовы onDeallocBlocks //лечим циклическую ссылку __block id self_ = self; [
addOnDeallocBlock: ^
{
[ [ NSNotificationCenter defaultCenter ] removeObserver: self_ ];
} ];

Слайд 25

Отложенные вызовы Scheduled operations

[ self performSelector: @selector( someMethod )
withObject: nil
afterDelay:

Отложенные вызовы Scheduled operations [ self performSelector: @selector( someMethod ) withObject: nil
20. ];
[ NSObject cancelPreviousPerformRequestsWithTarget: self ]; //отмена
ИЛИ
[ NSTimer scheduledTimerWithTimeInterval: 20.
target: self
selector: @selector( someMethod )
userInfo: nil
repeats: YES ];
[ timer_ invalidate ]; //отмена

Слайд 26

Отложенные вызовы Scheduled operations


__block id self_ = self;
JFFScheduledBlock bk_= ^
{

Отложенные вызовы Scheduled operations __block id self_ = self; JFFScheduledBlock bk_= ^
[ self_ someMethod ];
}
CancelBlock cancel_ = [ JFFScheduler addBlock: bk_
duration: 20. ];
[ self addOnDeallocBlock: cancel_ ];

Слайд 27

Блоки вместо делегатов в UIAlertView

-(void)alertView:( UIAlertView* )alert_view_ clickedButtonAtIndex:( NSInteger )button_index_
{
NSString* title_

Блоки вместо делегатов в UIAlertView -(void)alertView:( UIAlertView* )alert_view_ clickedButtonAtIndex:( NSInteger )button_index_ {
= [ alert_view_ buttonTitleAtIndex: button_index_ ];
if ( [title_ isEqualToString: cancel_ ] )
//..
else if ( [ title_ isEqualToString: button1_ ] )
//..
else if ( [ title_ isEqualToString: button2_ ] )
//..
}

Слайд 28

Блоки вместо делегатов в UIAlertView

JFFAlertButton* bt_ = [ JFFAlertButton alertButton: title_
action:

Блоки вместо делегатов в UIAlertView JFFAlertButton* bt_ = [ JFFAlertButton alertButton: title_
^
{
//do some action
} ];
JFFAlertView* alert_view_ =
[ JFFAlertView alertWithTitle: @"Alert2"
message: @"test"
cancelButtonTitle: @"Cancel"
otherButtonTitles: bt_, nil ];

Слайд 29

Обобщенное асинхронное программирование
1. Асинхронная операция в общем виде
2. Кеширование
3. Порядок выполнения
Дерево зависимостей,

Обобщенное асинхронное программирование 1. Асинхронная операция в общем виде 2. Кеширование 3.
login
Lazy load, вычитка страниц
4. Load balancer
5. Асинхронные операции в контексте сессии
6. Асинхронные операции в UI

Слайд 30

Асинхронная операция в общем виде
CancelBlock (^AsyncOperation)
( ProgressHandler
, CancelHandler
, FinishHandler

Асинхронная операция в общем виде CancelBlock (^AsyncOperation) ( ProgressHandler , CancelHandler ,
) { … };

Слайд 31

Кеширование

Физический запрос

Логический запрос 1

Логический запрос 2

Ответ 1

Ответ 2

Кеширование Физический запрос Логический запрос 1 Логический запрос 2 Ответ 1 Ответ 2

Слайд 32

Кэширование, API
//физический запрос
JFFAsyncOperation data_loader_ = ...;
//кэшированный запрос
JFFAsyncOperation cached_loader_

Кэширование, API //физический запрос JFFAsyncOperation data_loader_ = ...; //кэшированный запрос JFFAsyncOperation cached_loader_
=
[ self asyncOperationForPropertyWithName: @”image”
asyncOperation: data_loader_ ];

Слайд 33

Порядок выполнения - последовательность
sequence_ = sequenceOfAsyncOperations ( operation1_
, operation2_
, nil );

Асин.

Порядок выполнения - последовательность sequence_ = sequenceOfAsyncOperations ( operation1_ , operation2_ ,
оп.1

Асин. оп.2

Асин. Оп.N


Асинхронная операция как последовательность

Слайд 34

Порядок выполнения - группа
group_ = groupOfAsyncOperations ( operation1_
, operation2_
, nil );

Запрос

Порядок выполнения - группа group_ = groupOfAsyncOperations ( operation1_ , operation2_ ,
3

Запрос 1

Запрос 2

Группа запросов

Слайд 35

Порядок выполнения – граф ленивые вычисления
JFFAsyncOperation other_pages_ = ^( callbacks_ )
{
NSArray* loaders_

Порядок выполнения – граф ленивые вычисления JFFAsyncOperation other_pages_ = ^( callbacks_ )
= …;
result_ = groupOfAsyncOp( loaders_ );
return result_( callbacks_ );
};
sequenceOfAsyncOperations( first_page_
, other_pages_
, nil );

Слайд 36

Load balancer
//имя текущего контекста
void setBalancerActiveContextName( NSString* name_ );
//сбалансированная асинхронная операция
balanced_loader_ = balancedAsyncOperation(

Load balancer //имя текущего контекста void setBalancerActiveContextName( NSString* name_ ); //сбалансированная асинхронная
loader_ );

Слайд 37

Запросы и сессия
safe_loader_ = checkSessionForLoaderBlock( loader_ )

Login

Logout

Запросы и сессия safe_loader_ = checkSessionForLoaderBlock( loader_ ) Login Logout

Слайд 38

Легкий делегат

{
[ self.clip asyncImageWithWeakDelegate: self ];
}
#pragma mark ClipDelegate
-(void)clip:( Clip* )clip_
didLoadImage:(

Легкий делегат { [ self.clip asyncImageWithWeakDelegate: self ]; } #pragma mark ClipDelegate
UIImage* )image_
error:( NSError* )error_
{
if ( self.clip != clip_ )
return;
self.imageView.image = image_;
}

Слайд 39

Легкий делегат


JFFAsyncOperation loader_ = …;
__block id weak_delegate_ = delegate_;

Легкий делегат JFFAsyncOperation loader_ = …; __block id weak_delegate_ = delegate_; [
[ weak_delegate_ weakAsyncOperation: loader_ ]
( nil, nil, ^( id image_, NSError* error_ )
{
[ weak_delegate_ clip: self
didLoadImage: image_
error: error_ ];
} );

Слайд 40

Легкий делегат ARC

JFFAsyncOperation loader_ = …;
weak id weak_delegate_ = delegate_;

Легкий делегат ARC JFFAsyncOperation loader_ = …; weak id weak_delegate_ = delegate_;
loader_( nil
, nil
, ^( id image_
, NSError* error_ )
{
[ weak_delegate_ clip: self
didLoadImage: image_
error: error_ ];
} );
Имя файла: Objective-C-Блоки-(Block).pptx
Количество просмотров: 633
Количество скачиваний: 0