Objective-C Блоки (Block). Тип и литерал блока typedef int (^MyBlock)(int); int multiplier = 7; MyBlock myBlock = ^(int num) { return num * multiplier;

Презентация:



Advertisements
Похожие презентации
Программирование Mac OS. История возникновения Архитектура Инструменты разработки Язык Библиотеки План.
Advertisements

Ошибки при работе с памятью на iOS Поиск причин падений в связи с Low Memory и EXC_BAD_ACCESS.
Test 16 Вопрос 1. class Clazz { { System.out.println("non-static init"); } public static void main(String a[]) { System.out.println("main"); Clazz ob1.
В. М. Гуровиц, Глобальные функции объявляются в самой программе или в модуле и доступны из любого места программы Локальные функции.
Точечные взаимодействия. Назначение точечных взаимодействий.
Стеки и очереди 1. Абстрактный стек public interface Stack { static class Underflow extends Exception { public Underflow() { super("Stack underflow");
Using Dreamweaver MX Slide 1 Window menu Manage Sites… Window menu Manage Sites… 2 2 Open Dreamweaver 1 1 Set up a website folder (1). Click New…
Введение в разработку под iOS (более плотное). Вас ждет огромное количество информации. Не пытайтесь её запомнить и переварить, лучше запишите главное.
QML – новый подход к построению GUI. Введение Подходы к построению десктопных приложений: Императивный Декларативный QML - это декларативный язык, предназначенный.
Часть II. Формальное описание языков программирования ( Формальная спецификация формальных языков ) Приложение. Грамматика языка IMP в форме BNF.
Class Date { private int year = 0; private int month = 0; private int day = 0; public void SetDate (int y, int m, int d) { year = y; month = m; day = d;
WiseImage Open Architecture Lessons Mission Impossible.
Test21 Вопрос 1. public class Test { void a1(Object... i){ System.out.println("[Object... i]"); } void a1(Integer... i){ System.out.println("[Integer...
Date: File:GRAPH_05e.1 SIMATIC S7 Siemens AG All rights reserved. SITRAIN Training for Automation and Drives Documentation and ASCII Archives.
Date: File:GRAPH_05e.1 SIMATIC S7 Siemens AG All rights reserved. SITRAIN Training for Automation and Drives Документирование и архивы.
Info My name – Valera Kolupaev – Wave for questions -
PHP как язык программированияPHP как язык программирования.
Язык Ruby Денис С. Мигинский. Ruby Создан Юкихиро Мацумото в 1995 г. В основу положены элементы языков Perl, Python, Lisp, Smalltalk и др., а также «принцип.
Searching Lesson Plan - 6. Contents Evocation Objective Introduction Sequential Search Algorithm Variations on sequential search Mind map Summary.
Исключения в Java Макаревич Л. Г.. Исключения – это механизм взаимодействия между кодом, приведшим к ошибке, и кодом, обрабатывающим ошибку Исключение.
Транксрипт:

Objective-C Блоки (Block)

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

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

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

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

Контекст блока 3. переменные – указатели на объекты с подсчетом ссылок (id, NSObject) NSDate* date = [ [ NSDate alloc ] init ]; void (^printDate)() = ^() { date ); }; //копируем блок в кучу printDate = [ [ printDate copy ] autorelease ]; [ date release ]; printDate();

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

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

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

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

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

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

Automatic Reference Counting No copy, release and autorelease

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Порядок выполнения - последовательность sequence_ = sequenceOfAsyncOperations ( operation1_, operation2_, nil ); Асин. оп.1 Асин. оп.2 Асин. Оп.N … Асинхронная операция как последовательность

Порядок выполнения - группа group_ = groupOfAsyncOperations ( operation1_, operation2_, nil ); Запрос 3 Запрос 1 Запрос 2 Группа запросов

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

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

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

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

Легкий делегат 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_ ]; } );

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

Всем спасибо !!! Skype: vova.gorbenko.mac