среда, 26 августа 2015 г.

20. IBOutlet

Видео урок 20 находится здесь:
В этом видео рассказывается о том как создавать элементы (конкретно UIView ) в Storyboard. Как настраивать этот элемент используя интерфейс storyboard.
Так же показано, как с помощью сториборд создавать переменные IBOutlet  и связывать их с view.
Так же рассказано о применение IBOutletCollection - массива объединяющий несколько элементов UIView.
Так же элементам  UIView можно задавать Tag для  дальнейшей идентификации

Проект с уроком 20 находится здесь.

Домашнее задание к уроку 20 IBOutlet:

На самом деле урок очень простой, единственно что я рекомендую повторить прошлое домашнее задание, но используя аутлеты. Итак:

ВСЕ ЗАДАНИЯ ДОЛЖНЫ БЫТЬ БЫПОЛНЕНЫ ТОЛЬКО ИСПОЛЬЗУЯ АУТЛЕТЫ.
МЕТОД subviews НЕ ИСПОЛЬЗУЙТЕ, ВМЕСТО НЕГО ИСПОЛЬЗУЙТЕ АУТЛЕТ КОЛЛЕКЦИИ

Ученик

1. В цикле создавайте квадратные UIView с черным фоном и расположите их в виде шахматной доски
2. доска должна иметь столько клеток, как и настоящая шахматная

Студент

3. Доска должна быть вписана в максимально возможный квадрат, т.е. либо бока, либо верх или низ должны касаться границ экрана
4. Применяя соответствующие маски сделайте так, чтобы когда устройство меняет ориентацию, то все клетки растягивались соответственно и ничего не вылетало за пределы экрана.

Мастер
5. При повороте устройства все черные клетки должны менять цвет :)
6.Сделайте так, чтобы доска при поворотах всегда строго находилась по центру

Супермен
8. Поставьте белые и красные шашки (квадратные вьюхи) так как они стоят на доске. Они должны быть сабвьюхами главной вьюхи (у них и у клеток один супервью)
9. После каждого переворота шашки должны быть перетасованы используя соответствующие методы иерархии UIView


Не доделал домашнее задание, т.к. запарился  два часа перетаскивать и настраивать каждый из более 50 UIView в StoryBoard. Принцип понятен, а тупо сидеть и перетаскивать надоело.
Весь код есть в предыдущем домашнем задании.

суббота, 22 августа 2015 г.

19. UIView

В этом уроке рассказывается о создании View и Subview.


    UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(100, 150, 200, 50)];
    view1.backgroundColor=[[UIColor redColor] colorWithAlphaComponent:0.8];

    [self.view addSubview:view1];

Так же рассказывается об автоматическом изменении размеров вью.
В маске описаны границы view которые изменяются (другие жестко привязаны)
  view2.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleBottomMargin;

Чтобы переместить вью на верхний уровень:

    [self.view bringSubviewToFront:view1];

Вот метод для поддержки всех видов поворота экрана:

-(UIInterfaceOrientationMask   ) supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskAll;
}

Объясняются такие понятия как frame  и bounds.

Фрейм координаты задаются относительно главного окна.
Боундс это внутренние координаты view

Исходники тестового проекта урока 19.


Домашнее задание к уроку 19.

Ученик

1. В цикле создавайте квадратные UIView с черным фоном и расположите их в виде шахматной доски
2. доска должна иметь столько клеток, как и настоящая шахматная

Студент

3. Доска должна быть вписана в максимально возможный квадрат, т.е. либо бока, либо верх или низ должны касаться границ экрана
4. Применяя соответствующие маски сделайте так, чтобы когда устройство меняет ориентацию, то все клетки растягивались соответственно и ничего не вылетало за пределы экрана.

Мастер
5. При повороте устройства все черные клетки должны менять цвет :)
6.Сделайте так, чтобы доска при поворотах всегда строго находилась по центру

Супермен
8. Поставьте белые и красные шашки (квадратные вьюхи) так как они стоят на доске. Они должны быть сабвьюхами главной вьюхи (у них и у клеток один супервью)
9. После каждого переворота шашки должны быть перетасованы используя соответствующие методы иерархии UIView

Выполнены все пункты домашнего задания к уроку 19 (ученик, студент, мастер, супермен).


Проект с домашним заданием находится здесь.

среда, 19 августа 2015 г.

18. Пример разработки RoboWars

В первой части урока, Алексей дает наставления как писать хороший код, прорабатывать все этапы на бумаге и много других ценных советов.
Во второй части на собственном примере за час пишет робота для игры Robowars.
В процессе написания робота рассматривается много функций по работе с CGRect, CGPoint  и др.

В этом уроке нет домашнего задания.

17. UIViewController

Урок 17 находящийся здесь
является вводным в UIViewController.
В нем объясняется базовые моменты в UIView Controller.

Функции которые запускаются в процессе запуска и работы приложения:

Первый метод, (после loadView) вызываемый после запуска UIViewController:
- (void)viewDidLoad

 Метод который вызывается до появления представления
-(void) viewWillAppear:(BOOL)animated

Метод который вызывается после появления представления
-(void) viewDidAppear:(BOOL)animated

Метод вызывается перед тем, как представление закроется
-(void) viewWillDisappear:(BOOL)animated

Метод вызывается после того, как представление закроется.

-(void) viewDidDisappear:(BOOL)animated



-(void) viewWillLayoutSubviews


Некоторые методы описанные в видео-уроке уже устарели (deprecated)  и  их нельзя использовать в новых версиях Xcode.

     -(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation

Вместо этого метода нужно использовать следующую конструкцию:

 - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
     {
         UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
         // do whatever
                 
switch (orientation) {
             case UIInterfaceOrientationLandscapeLeft: 
     ....

     } completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
     {
         //some code
     }];
   
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}


Выполнил небольшое домашнее задание к уроку.
Программа выводит на  экран на каком устройстве запущена (iPhone,iPad).
Выводит текущее положение экрана (портрет, горизонтальное левое и т.д.).
Так же выводит имена функции которые запускаются при старте контроллера.
Вот здесь видео-демонстрация программы.


Здесь исходный код домашнего задания к уроку 17.


 Вот некоторые моменты
Определение на каком устройстве запускается программа.
Здесь же функция setText устанавливает текст в поле Label.

    if (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad){
        [self.deviceLabel setText:@"Device Ipad"];
       
    }
    else{
        if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone){
            [self.deviceLabel setText:@"Device Iphone"];
        }
    }

вторник, 18 августа 2015 г.

16. Время и дата.

В этом  уроке рассказывается как работать с датой, временем, таймерами.

Метод date возвращает текущую время и дату:
    NSDate *date =[NSDate date];
     NSLog(@"Date: %@",date);

Можно создать дату используя временные интервалы в секундах
  NSLog(@"%@",[date dateByAddingTimeInterval:5000] );
    NSLog(@"%@",[date dateByAddingTimeInterval:-5000] );

Сравнение двух дат:
   [date compare:[date dateByAddingTimeInterval:-5000]];

Вот еще один метод создание даты с 2001г
    NSDate *date2=[NSDate dateWithTimeIntervalSinceReferenceDate:10];
    NSLog(@"date2=%@",date2);

ДатаФорматтер используется для форматировании вывода даты и времени

    NSDateFormatter * dateFormatter=[[NSDateFormatter alloc]init];



Метод setDateStyle используется чтобы выбрать один из типов вывода даты

    [dateFormatter setDateStyle:NSDateFormatterShortStyle];
    NSLog(@"NSDateFormatterShortStyle %@",[dateFormatter stringFromDate:date]);

  [dateFormatter setDateStyle:NSDateFormatterNoStyle];
    NSLog(@"NSDateFormatterNoStyle %@",[dateFormatter stringFromDate:date]);

Можно задать свой формат даты:

[dateFormatter setDateFormat:@"yy/MM/dd EEEE HH:mm:SS a w"];

    [dateFormatter setDateFormat:@"yy/MM/dd HH:mm"];
    NSLog(@"my style: %@",[dateFormatter stringFromDate:date]);

Можно сформировать дату из строки:
    NSDate *date3=[dateFormatter dateFromString:@"08/05/17 15:37"];
    NSLog(@"my date: %@",date3);

Можно использовать календарь
    NSDate * d=[NSDate date];
   
    NSCalendar * calendar= [NSCalendar currentCalendar];
  //  NSDateComponents *component=[calendar component:NSCalendarUnitEra fromDate:d  ];
   // NSLog(@"%@",component);

 NSDate *date1=[NSDate date];
    NSDate *date2=[NSDate dateWithTimeIntervalSinceNow:-1000000];

    NSCalendar *calendar=[NSCalendar currentCalendar];
    NSDateComponents * components=
    [calendar components:NSCalendarUnitDay|NSCalendarUnitMinute fromDate:date1 toDate:date2 options:0];
    NSLog(@"%@",components);

Для создания таймера необходимо использовать:
       NSTimer* timer1= [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerTest:) userInfo:nil repeats:YES];


 и создать функцию таймера:

-(void) timerTest: (NSTimer*) timer{
   

    NSDateFormatter *dateFormater=[[NSDateFormatter alloc] init];
    [dateFormater setDateFormat:@"yy/MM/dd HH:mm:ss"];
    NSLog(@"%@",[dateFormater stringFromDate:[NSDate date  ]]);
 
   
}
}


Таймер так же необходимо правильно уничтожать, чтобы небыло утечки памяти:
  [timer invalidate];


Тестовый проект с уроком 16 Время и дата.



Домашнее задание к уроку 16 Время и дата.

Ученик.

1. Создайте класс студент у когторого будет проперти dateOfBirth (дата рождения), которая собственно NSDate.
2. Инициализируйте NSMutableArray и в цикле создайте 30 студентов.
3. Каждому установите дату рождения. Возраст рандомный от 16 до 50 лет.
4. В другом цикле пройдитесь по всему массиву и выведите день рождения каждого студента в адекватном формате.

Студент.

5. Отсортируйте массив студентов по дате рождения, начиная от самого юного.
6. Используя массивы имен и фамилий (по 5-10 имен и фамилий), каждому студенту установите случайное имя и случайную фамилию.
7. Выведите отсортированных студентов: Имя, Фамилия, год рождения

Мастер.

10. Создайте таймер в апп делегате, который отсчитывает один день за пол секунды.
11. Когда таймер доходит до дня рождения любого их студентов - поздравлять его с днем рождения.
12. Выведите на экран разницу в возрасте между самым молодым и самым старым студентом (количество лет, месяцев, недель и дней)

Супермен.

13. Выведите на экран день недели, для каждого первого дня каждого месяца в текущем году (от начала до конца)
14. Выведите дату (число и месяц) для каждого воскресенья в текущем году (от начала до конца)
15. Выведите количество рабочих дней для каждого месяца в текущем году (от начала до конца)

Выполнены все задания.

Проект домашнего задания к уроку 16 Дата.





понедельник, 17 августа 2015 г.

15. Битовые операции.

Видео урок находится здесь.
В этом уроке рассказывается о двоичном представлении числа.
Что такое побитовое сложение или |.
Что такое побитовое и или умножение &.
Что такое исключающее или ^ и ~ инверсия.

Показано, как красиво (в стиле Apple) оформлять Enum для масок:
typedef enum{
    TAStudentSubjectTypeBiology      =1<<0,
    TAStudentSubjectTypeMath         =1<<1,
    TAStudentSubjectTypeDevelopment      =1<<2,
    TAStudentSubjectTypeEngineering      =1<<3,
    TAStudentSubjectTypeArt      =1<<4,
    TAStudentSubjectTypePsychology      =1<<5,
    TAStudentSubjectTypeAnatomy      =1<<6
} TAStudentSubjectType;


С помощью или |  устанавливаются все значения:
 student.subjectType= TAStudentSubjectTypeAnatomy|TAStudentSubjectTypeDevelopment|                   TAStudentSubjectTypeEngineering|TAStudentSubjectTypeMath;


Для вывода и проверки установлено ли значение применяется битовое & -  умножение
-(NSString *) answerByType: (TAStudentSubjectType) type{
    return self.subjectType&type?@"yes":@"no";
}
[self answerByType:TAStudentSubjectTypeBiology],

Еще фишка одна.
Чтобы выводить объект в NSLog необходимо переопределить метод -(NSString *) description;

Проект с уроком находится здесь.



Домашнее задание к уроку 15 Битовые маски:

Ученик.

1. Повторите мой код и создайте класс студент с соответствующим набором предметов
2. В цикле создайте 10 студентов и добавьте их в массив. Используйте мутабл массив
3. У каждого рандомно установите предметы

Студент

4. В новом цикле пройдитесь по студентам и разделите их уже на два массива - технари и гуманитарии.
5. Также посчитайте количество тех кто учит программирование

Мастер.

6. Если студенты выбрали биологию, то отмените ее у них и выведите сообщение в лог, предмет отменен
7. Тут придется разобраться как сбросить бит, включите логику :)

Супермен.
8. Сгенерируйте случайный интежер в диапазоне от 0 до максимума.
9. Используя цикл и битовые операыии (и возможно NSMutableString) выведите это число на экран в двоичном виде


Выполнены все задания к уроку (ученик, студент, мастер, супермен) 15.
Проект с домашним заданием к уроку 15 - битовые операции.

пятница, 14 августа 2015 г.

14. Строки

Видео-урок находится здесь.
В этом уроке рассмотрены много методов для работы со строками.
Сравнение двух строк:

 anyString isEqualToString:@"String1"

Рассмотрена структура NSRange, для определения расположения подстроки которая имеет  location - которое указывает на место в строке (с 0) и length - длина подстроки.

Поиск подстроки в строке можно сделать rangeOfString в options:NSCaseInsensitiveSearch|NSBackwardsSearch указываются дополнительные маски или опции (в данном случае поиск без учета заглавных букв и поиск с конца).



   NSString *string=@"Hello World World!";
    NSRange range=[string rangeOfString:@"world" options:NSCaseInsensitiveSearch|NSBackwardsSearch];

после поиска нужно проверять нашлась ли подстрока в строке:

    if (range.location!=NSNotFound) {
        NSLog(@"Range=%@",NSStringFromRange(range));

    }
    else{
          NSLog(@"Range not found");
    }


Обрезание строки с 0 по 30 индекс:
text=[text substringToIndex:30];

Вырезка подстроки с нужного места

text=[text substringWithRange:NSMakeRange(1, 4)];


Поиск и замена одной подстроки на другую (в тексте):
text=[text stringByReplacingOccurrencesOfString:@"to" withString:@"LA-LA"];

Превращение всех букв в заглавные:
text=[text uppercaseString];

Каждое слово с заглавной буквы:
text=[text capitalizedString];

Превращение текста в массив строк используя разделитель
    NSArray *array=[text componentsSeparatedByString:@" "];

Из массива соединение в текст используя разделитель:
    text=[array componentsJoinedByString:@"_"];

Слияние двух строк:
    NSString *s1=@"Hello ";
    NSString *s2=@"World";
    NSString* s3=[s1 stringByAppendingString:s2];


Домашнее задание к уроку 14 Строки.

Ученик.

1. Возьмите текст из моего исходника и создайте на его основе строку, с которой будете работать.
2. Выведите на экран сначала первую половину текста, а потом вторую.
3. Создайте массив, каждый элемент которого является предложением данного текста.

Студент.

4. Используя массив из пункта 3 создайте новый массив, элементы которого это предложения, содержащие слово NSString. Нужно будет использовать поиск и мутабл массивы.

Мастер.

5. Создайте новый массив на основе массива из пункта 4, но слова в предложении пусть идут наоборот, первое слово будет в конце, а последнее вначале :)

Супермен.

6.В оригинальном тексте каждое слово должно начинаться с маленькой буквы, а заканчиваться на заглавную.


Проект домашнего задания 14 Строки.

Выполнены все задания: Ученик, студент, мастер, супермен.



четверг, 13 августа 2015 г.

13. Многопоточность

Ссылка на видео урок.

Потоки делятся на главный и фоновые.
Раньше мы работали с главным потоком.

Простейший способ запустить свой метод (testThread) в фоновый поток:

 [self performSelectorInBackground:@selector(testThread) withObject:nil];

Более продвинутый способ с дополнительными настройками и возможностями:

    //  NSThread * thread=[[NSThread alloc] initWithTarget:self selector:@selector(testThread) object:nil];
    //[thread start];

Можно задать имя потоку:
    thread1.name=[NSString stringWithFormat:@"Thread X"];


Для вывода результата запускаем метод вывода с задержкой 5 секунд:
    [self  performSelector:@selector(printArray) withObject:nil afterDelay:5];


Более быстрый способ запуска потоков через dispatch_queue и блоки:

dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{ код потока });


Полезная функция для фиксирования времени выполнения потока
        double startTime=CACurrentMediaTime();

Вывод имени текущего потока и времени  его работы
            NSLog(@"Thread: %@ finished in %@",[[NSThread currentThread] name],@( CACurrentMediaTime()-startTime));



Вывод имени потока и его типа( главный или фоновый):
        NSLog(@"%@ started. This is %@ thread",[[NSThread currentThread] name],[[NSThread currentThread] isMainThread]?@"Main":@"Background");


Потоки лучше заключать в авторелизпул:
   @autoreleasepool { }

Для синхронизации потоков при обращении к общему ресурсу можно использовать:
@synchronized(self) {}

Файлы проекта урока 13 Многопоточность.

Домашнее задание к 13 уроку.
Ученик.

1. Создайте класс студент. У него должен быть метод - угадать ответ :)
2. В метод передается случайное целое число например в диапазоне от 0 - 100 (или больше) и сам диапазон, чтобы студент знал где угадывать
3. Студент генерирует случайное число в том же диапазоне пока оно не будет искомым
4. Весь процесс угадывания реализуется в потоке в классе студент
5. Когда студент досчитал то пусть пишет в НСЛог
6. Создайте 5 студентов и дайте им одну и туже задачу и посмотрите кто справился с ней лучше

Студент.

7. Задача та же, но вместе с условием передавайте студенту блок, в котором вы и объявите результаты
8. Блок должен определяться в томже классе, где и определялись студенты
9. Блок должен быть вызван на главном потоке

Мастер.

10. Создать приватный метод класса (да да, приватный метод да еще и с плюсом), который будет возвращать статическую (то есть одну на все объекты класса студент) dispatch_queue_t, которая инициализируется при первом обращении к этому методу.
11. Лучше в этом методе реализовать блок dispatch_once, ищите в инете как и зачем :) А что, программист всегда что-то ищет и хороший программист всегда находит.
12. Все студенты должны выполнять свои процессы в этой queue и она должна быть CONCURRENT, типа все блоки одновременно выполняются

Супермен.

13. Добавьте еще один класс студента, который делает все тоже самое что вы реализовали до этого, только вместо GCD он использует NSOperation и NSOperationQueue. Вообще вынос мозга в самостоятельной работе :)
14. Все сделавшие Мастера и Супермена и с красивым кодом получают отдельный огромный РЕСПЕКТ, так как они это на самом деле заслуживают.

Выполнил задания для ученика, студента, мастера и супермена.
Код домашнего задания к уроку 13 Многопоточность.


среда, 12 августа 2015 г.

12. Блоки

Ссылка на урок.
В Этом уроке рассмотрены блоки.
Блок  это фрагмент кода, имеющий имя,  который можно использовать повторно.
Пример объявления блока  (ничего не возвращающего и не принимающего).
Второй строкой идет инициализация блока.

    void (^testBlock)(void);

        testBlock = ^{     NSLog(@"test block"); };

Вызов на выполнение блока:

 testBlock();

Можно определить свой тип:
typedef void(^OurTestBlock)(void);

OurTestBlock testBlock =  ^{     NSLog(@"test block"); };


Определение и инициализация (одной строкой) блока с параметрами + вызов:

    void (^testBlockWithParams)(NSString*,NSInteger)=^(NSString *string, NSInteger intValue){
        NSLog(@"Test block with parametrs: string: %@, int: %@",string ,@(intValue));
    };
   
    testBlockWithParams(@"test string",33);

Определение, инициализация и вызов блока возвращающего значение с параметрами:

   NSString * (^testBlockWithReturnValueAndParams)(NSString*,NSInteger)=^(NSString *string, NSInteger intValue){
        return [NSString stringWithFormat: @"Test Block with Return value and parametrs: string: %@, int: %@",string ,@(intValue)];
    };
   
    NSLog(@"%@", testBlockWithReturnValueAndParams(@"string method with return",13));


Блок видит переменные используемые за пределами блока.
Чтобы изменять внешние переменные в блоке используется конструкция __block
    __block NSString * testString=@"how is it possible?";
   
    void (^testBlock2)(void);
    __block NSInteger i=0;
   
    testBlock2 = ^{
        i++;
        //NSLog(@"test block2");
        testString=[NSString stringWithFormat:@"How is it possible: %@",@(i)];
        NSLog(@"%@",testString);
    };
    testBlock2();
    testBlock2();

Блок можно передать в качестве параметра в метод:
    [self testBlocksMethod:^{
        NSLog(@"BLOCK");
    }];

Определение метода:
 -(void) testBlocksMethod : (void (^)(void)) testBlock {

    NSLog(@"TestBlockMethod");
    testBlock();
}

 Использование блока для сортировки массивов:

    NSArray *array=nil;
    NSComparisonResult (^bb)(id , id )=^(id  __nonnull obj1, id  __nonnull obj2){
        return NSOrderedAscending;
    };
   
    array=[array sortedArrayUsingComparator:bb];

Если блок используется в качеств проперти, То необходимо указывать тип ссылки @property(copy)

Чтобы не было утечки памяти в случае если  блок и другое property ссылаются друг на друга, необходимо использовать  конструкцию __weak:

 typedef void (^objectBlock)(void);
@interface TAObject : NSObject

@property(strong,nonatomic) NSString * name;
@property (copy,nonatomic) objectBlock objBlock;
 @end

@implementation TAObject

- (instancetype)init
{
    self = [super init];
    if (self) {
        __weak TAObject *weakSelf=self;
       
        self.objBlock=^{
            NSLog(@"%@",weakSelf.name);
        };
    }
    return self;
}


еще пример:

@interface AppDelegate ()
@property (copy ,nonatomic) OurTestBlock testBlock;
@property(strong,nonatomic)NSString *name;

@end

    TAObject *  obj= [[TAObject alloc]init];
    obj.name= @"OBJECT";
    __weak TAObject * weakObj=obj;
   
    self.testBlock=^{
        NSLog(@"%@",weakObj.name  );
    };
    self.testBlock();




В блоке та же видимость переменных, что и за пределами блока.

Пример какой объект блок будет считать за self:
    TAObject *  obj1= [[TAObject alloc]init];
    obj1.name= @"OBJECT";
    self.name=@"hello";
    [obj1 testMethod:^{
        NSLog(@"%@",self.name);
    }];

Вывод: hello .


Исходный проект с тестовым уроком 12 Блоки


   
Домашнее задание к уроку 12 - Блоки.
Ученик. Фактически это повторить первую половину.

1. В апп делегате создайте блок с без возвращаемой переменной и без параметров и вызовите его.
2. Создайте блоки с параметрами и передайте туда строку, которую выведите на экран в последствии.
3. Если вы не определили тип данных для ваших блоков, то сделайте это сейчас и используйте их
4. Создайте метод который принимает блок и вызывает его и вызовите этот метод.

Студент.
5. Создайте класс студент с проперти имя и фамилия.
6. Создайте в аппделегате 10 разных студентов, пусть у парочки будут одинаковые фамилии.
7. Поместите всех в массив.
8. Используя соответствующий метод сортировки массива (с блоком) отсортируйте массив студентов сначала по фамилии, а если они одинаковы то по имени.

Мастер.
9. Задание из видео. Из урока о делегатах. У пациентов удалите протокол делегат и соответствующее проперти.
10. Добавьте метод принимающий блок когда им станет плохо.
11. Блок должен передавать указатель на самого студента ну и на те параметры, которые были в задании по делегатам.
12. Теперь когда пациентам поплохеет, они должны вызывать блок, а в блоке нужно принимать решения что делать (доктор не нужен делайте все в апп делегате)

Супермен
13. Познайте истинное предназначение блоков :) Пусть пациентам становится плохо не тогда когда вы их вызываете в цикле(это убрать), а через случайное время 5-15 секунд после создания (используйте специальный метод из урока по селекторам в ините пациента).
14. не забудьте массив пациентов сделать проперти аппделегата, а то все помрут по выходе из функции так и не дождавшись :)



Выполнил все задания (ученик, студент, мастер, супермен).
Проект с домашним заданием к уроку №12 блоки.

Вывод консоли получился такой:
 2015-08-13 17:14:52.495 DZ12Block[3330:104595] Pupil homeWork DZ12
2015-08-13 17:14:52.496 DZ12Block[3330:104595] blockTest1 without parametrs
2015-08-13 17:14:52.496 DZ12Block[3330:104595] blocktest2 without parametrs return string
2015-08-13 17:14:52.496 DZ12Block[3330:104595] Own blocktype with parametr and no return
2015-08-13 17:14:52.497 DZ12Block[3330:104595] Own blocktype1 with parametr and  return string
2015-08-13 17:14:52.497 DZ12Block[3330:104595] block receive into method test string1 into test block5
2015-08-13 17:14:52.497 DZ12Block[3330:104595] testBlockMethod: return testblock5:test string1 into test block5, str-method`s parametr: string`s parametr method`s testBlockMethod
2015-08-13 17:14:52.497 DZ12Block[3330:104595] Student homeWork DZ12
2015-08-13 17:14:52.498 DZ12Block[3330:104595] Dubovoi Sergey
2015-08-13 17:14:52.498 DZ12Block[3330:104595] Ivanov Dima
2015-08-13 17:14:52.498 DZ12Block[3330:104595] Ivanov Kostya
2015-08-13 17:14:52.499 DZ12Block[3330:104595] Ivanov Vasya
2015-08-13 17:14:52.499 DZ12Block[3330:104595] Petrov Petya
2015-08-13 17:14:52.499 DZ12Block[3330:104595] Petrova Lusia
2015-08-13 17:14:52.585 DZ12Block[3330:104595] Sidorov Vasya
2015-08-13 17:14:52.585 DZ12Block[3330:104595] Strelcova Ola
2015-08-13 17:14:52.585 DZ12Block[3330:104595] Voronina Ira
2015-08-13 17:14:52.585 DZ12Block[3330:104595] Voronina Natasha
2015-08-13 17:14:52.586 DZ12Block[3330:104595] Master homeWork DZ12
2015-08-13 17:14:52.586 DZ12Block[3330:104595] Vasya temperature:39.5 and Head Ache.
2015-08-13 17:14:52.587 DZ12Block[3330:104595] Patient Vasya temperature: 39.5 Ache: Head Ache. Treat headache
2015-08-13 17:14:52.587 DZ12Block[3330:104595] Vasya treat. Rating doctor: 5
2015-08-13 17:14:52.594 DZ12Block[3330:104595] Kolya temperature:38.5 and Stomach stomachache.
2015-08-13 17:14:52.598 DZ12Block[3330:104595] Patient Kolya temperature: 38.5 Ache: Stomach stomachache. Treat Heartache
2015-08-13 17:14:52.599 DZ12Block[3330:104595] Kolya treat. Rating doctor: 1
2015-08-13 17:14:52.599 DZ12Block[3330:104595] Dima temperature:40.5 and ToothAche Ache.
2015-08-13 17:14:52.600 DZ12Block[3330:104595] Patient Dima temperature: 40.5 Ache: ToothAche Ache. Treat ToothAche
2015-08-13 17:14:52.766 DZ12Block[3330:104595] Dima treat. Rating doctor: 2
2015-08-13 17:14:52.766 DZ12Block[3330:104595] Natasha temperature:37 and Heart heartache.
2015-08-13 17:14:52.767 DZ12Block[3330:104595] Patient Natasha temperature: 37 Ache: Heart heartache. Treat Heartache
2015-08-13 17:14:52.768 DZ12Block[3330:104595] Natasha treat. Rating doctor: 4
2015-08-13 17:14:52.769 DZ12Block[3330:104595] Denis temperature:36 and Head Ache.
2015-08-13 17:14:52.769 DZ12Block[3330:104595] Patient Denis temperature: 36 Ache: Head Ache. Treat headache
2015-08-13 17:14:52.770 DZ12Block[3330:104595] Denis treat. Rating doctor: 2
2015-08-13 17:14:52.770 DZ12Block[3330:104595] SuperMan homeWork DZ12
2015-08-13 17:14:52.777 DZ12Block[3330:104595] patient:Vasya deallocated
2015-08-13 17:14:52.777 DZ12Block[3330:104595] patient:Kolya deallocated
2015-08-13 17:14:52.777 DZ12Block[3330:104595] patient:Dima deallocated
2015-08-13 17:14:52.778 DZ12Block[3330:104595] patient:Natasha deallocated
2015-08-13 17:14:52.778 DZ12Block[3330:104595] patient:Denis deallocated
2015-08-13 17:15:00.776 DZ12Block[3330:104595] Dima temperature:36 and Head Ache.
2015-08-13 17:15:00.777 DZ12Block[3330:104595] Patient Dima temperature: 36 Ache: Head Ache. Treat headache
2015-08-13 17:15:01.776 DZ12Block[3330:104595] vasya temperature:39.5 and Head Ache.
2015-08-13 17:15:01.776 DZ12Block[3330:104595] Patient vasya temperature: 39.5 Ache: Head Ache. Treat headache
2015-08-13 17:15:01.778 DZ12Block[3330:104595] Dima temperature:40.5 and ToothAche Ache.
2015-08-13 17:15:01.779 DZ12Block[3330:104595] Patient Dima temperature: 40.5 Ache: ToothAche Ache. Treat ToothAche
2015-08-13 17:15:02.776 DZ12Block[3330:104595] Natasha temperature:37 and Heart heartache.
2015-08-13 17:15:02.777 DZ12Block[3330:104595] Patient Natasha temperature: 37 Ache: Heart heartache. Treat Heartache
2015-08-13 17:15:07.776 DZ12Block[3330:104595] Kolya temperature:38.5 and Stomach stomachache.
2015-08-13 17:15:07.777 DZ12Block[3330:104595] Patient Kolya temperature: 38.5 Ache: Stomach stomachache. Treat Heartache

11. Селекторы.

Ссылка на видеоурок.

Селекторы это названия методов.
Пример синтаксиса для разных методов с параметрами и без:


     SEL selector = @selector(testMethod);
    SEL selector1=@selector(testMethod:);
    SEL selector2=@selector(testMethod:andParametr2:);
    SEL secretSelector=@selector(superSecretText);
    SEL selInt=@selector(testMethodWithInteger:);
    NSInteger i=11;

Вызов методов через селекторы   с разным количеством параметров.

    [self performSelector:selector];
    [self performSelector:selector1 withObject:@"string"];
    [self performSelector:selector2 withObject:@"string" withObject:@"string2"];

Вызов метода с задержкой

[self performSelector:selector withObject:nil afterDelay:3];


    TAObject *testObject=[[TAObject alloc]init];
    [testObject performSelector:selector];

С помощью селектора можно вызвать метод, который не указан в h файле, но есть в реализации.

    NSLog(@"Secret %@",[testObject performSelector:secretSelector] );
    NSLog(@"Secret %@",[self performSelector:selInt withObject:[NSNumber  numberWithInt:i]] );


Преобразование в строку из селектора и наоборот:

    NSString* str= NSStringFromSelector(selector1);
   
    SEL sel=NSSelectorFromString(str);

через селекторы легко вызывать методы с параметрами - объектами. для вызова с параметрами -простыми типами (int,float,double) не сильно просто.
В качестве примера приводится текст вызова и сам метод
    SEL selec=@selector(testMethodParametr1: parametr2: parametr3:);
    NSMethodSignature *signature=[AppDelegate instanceMethodSignatureForSelector:selec ];
    NSInvocation *invocation=[NSInvocation invocationWithMethodSignature:signature];
    [invocation setTarget:self];
    [invocation setSelector:selec];
    NSInteger iVal=2;
    CGFloat fVal=3.1;
    double dVal=5.3f;
   
    NSInteger *p=&iVal;
    CGFloat *p2=&fVal;
    double *p3=&dVal;
    [invocation setArgument:p atIndex:2];
    [invocation setArgument:p2 atIndex:3];
    [invocation setArgument:p3 atIndex:4];
    [invocation invoke];
     NSString * string =nil;
    [invocation getReturnValue:&string];
    NSLog(@"string= %@",string );
   
    return YES;
}
-(NSString*) testMethodParametr1: (NSInteger) intValue parametr2: (CGFloat) floatValue parametr3: (double) doubleValue{
    return  [NSString stringWithFormat:@"int: %@,float: %@, double: %@",@(intValue),@(floatValue),@(doubleValue)];
   
   }


Проект с исходником урока

вторник, 11 августа 2015 г.

10. Нотификации

Видео урок находится по этому адресу.
В этом уроке рассматривается такой механизм как нотификации.
Так же в уроке применяется шаблон программирования одиночка (единый центр нотификаций)  и шаблон наблюдатель (observer).

Так же показана работа с глобальными переменными используемыми для нотификаций.
Синтаксис глобальных строковых переменных:
в h. файле:
extern NSString * const TAGovernmentTaXLevelDidChangeNotification;
extern NSString * const TAGovernmentTaXLevelUserInfoKey; //применяется для ключа в словаре dictionary

в m. файле инкапсулировано(скрыто) инициализация констант значениями:
NSString * const  TAGovernmentTaXLevelDidChangeNotification = @"TAGovernmentTaXLevelDidChangeNotification";

NSString * const TAGovernmentTaXLevelUserInfoKey=@"TAGovernmentTaXLevelUserInfoKey";

Для передачи переменных вместе с нотификацией создается словарь, где под нужным ключом (TAGovernmentTaXLevelUserInfoKey) сохраняется переменная (taxLevel в данном случае)

   NSDictionary * dictionary=[NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:taxLevel] forKey:TAGovernmentTaXLevelUserInfoKey];



далее  получаем указатель на единый центр нотификаций и отправляем ему нотификацию, сообщаем название события TAGovernmentSalaryDidChangeNotification и передаем словарь с записанной переменной по нашему ключу:


    [[NSNotificationCenter defaultCenter] postNotificationName:TAGovernmentSalaryDidChangeNotification object:nil userInfo:dictionary];

для того, чтобы подписаться на нотификацию TAGovernmentSalaryDidChangeNotification   (добавить наблюдателя) :
      NSNotificationCenter *ns=[NSNotificationCenter defaultCenter];
        [ns  addObserver:self selector:@selector(salaryChangeNotification:) name:TAGovernmentSalaryDidChangeNotification object:nil];

Функция вызываемая при получении нотификации:

 -(void) salaryChangeNotification: (NSNotification*) notification{}


 Сразу же при подписке на нотификацию делаем удаления наблюдателя (или отдельной нотификации) например в деструкторе:
-(void) dealloc{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
 
}

  (или отдельной нотификации)

//    [[NSNotificationCenter defaultCenter] removeObserver:self name:TAGovernmentTaXLevelDidChangeNotification object:nil];



 Для того, чтобы вытащить из словаря пришедшего с нотификацией нашу переменную:

    NSNumber * value=[notification.userInfo objectForKey:TAGovernmentSalaryUserInfoKey];
 
    CGFloat salary=[value floatValue];


Исходный текст проекта по уроку №10 Нотификации.

Домашнее задание к уроку 10.
Задание:

Ученик.

1. Используя мой код создать свой проект со своими классами и понять как оно работает
2. Добавить классы "пенсионер" и "бизнесмен"
3. Доктор следит за изменением зарплаты, бизнесмен должен следить за изменением налогов, а пенсионер за изменением пенсий.
4. Все классы: Доктор, Пенсионер и Бизнесмен долджны следить также и за средней ценой на товар.

Умничка.

5. Каждый из классов следит за инфляцией (процентный рост средней цены на товар) и оценивает свой потенциальный доход по отношению к инфляции, например размер пенсии к возможности купить продукты у пенсионера, либо новая прибыль за вычетом налогов у бизнесмена также по отношению к ценам на товар.

6. Не секрет что изменение этих характеристик оказывает разное влияние на разные слои населения, поэтому пусть в зависимости от уровня покупательской способности каждый класс выдает свои перлы.

Мастер.

7. Подпишите классы на нотификацию ухода приложения в бекграунд, чтобы когда нажимается кнопка HOME и приложение сворачивается, каждый объект заявлял о том что он идет спать

8. Тоже самое сделать для случая, когда приложение возвращается из свернутого состояния

Супермен

9. Создайте свой класс аналог апп делегату, только он не делегат приложения, но слушатель тех же самых нотификаций, какие методы есть у делегата. Грубо говоря у вашего класса должны быть теже методы, что и у апп делегата, но вызываться они должны путем нотификаций

10. Добавьте НСЛоги в каждый метод апп делегата и своего класса

11. Сворачивая и разварачивая приложение добивайтесь вызовов определенный методов делегата и тех же нотификаций и посмотрите что вызывается раньше - метод делегата или нотификация :)


Выполнил задания Ученик и Мастер.
Проект с домашним заданием

суббота, 1 августа 2015 г.

9. Делегаты

Видео урок находится здесь.
В этом уроке объясняется что такое делегат на примере класса пациентов и доктора (делегата) который их обслуживает.

Синтаксис делегата примерно такой:

@protocol TAPatientDelegate ;

@interface TAPatient : NSObject

Свойство - ссылка на делегат:
@property(weak,nonatomic) id  <TAPatientDelegate>  doctor;

-(BOOL) howAreYou;
-(void) takePill;
-(void) makeShot;
@end

@protocol TAPatientDelegate

методы делегата
-(void) patient:(TAPatient * )patient  hasQuestion:(NSString*) question;
-(void) patientFeelsBad: (TAPatient*) patient;

@end


пациент сам вызывает своего доктора (делегата).


Файлы проекта с уроком 9 Делегаты.

Домашнее задание  к уроку 9 Делегаты.



Ученик:

1. Создать пару пациентов и доктора по тому же принципу что и в видео. (Доктор делегат у пациентов)
2. У пациента пусть будет температура и другие симптомы, по которым доктор может принимать решение.
3. У пациента сделайте метод типа стало хуже и пусть когда станет хуже, то он идет к доктору
4. Всех пациентов объедините в массив и в цикле вызовите метод "стало хуже".
5. Доктор должен лечить каждого согласно симптомам.

Студент:

6. Создайте другой класс доктора, не наследника от первого доктора, например друг :)
7. этот друг должен лечить своих пациентов своими собственными методами и короче плохой он доктор
8. пусть кто-то ходит к врачу, а кто-то к нему
9. создайте пару разных объектов класса друг и пусть они лечат своих пациентов (чтобы понять что делегат это не класс, а объект)

Мастер:

10. Создайте список частей тела в делегате пациента (голова, живот, нога и тд) и когда пациент приходит к врачу, пусть говорит что болит.
11. Доктор должен принимать во внимание что болит
12. Создайте у доктора метод "рапорт". Пусть в конце дня, когда все уже нажаловались достаточно, доктор составит рапорт (выдаст имена) тех у кого болит голова, потом тех у кого болел живот и тд

Супермен

13. Создайте в классе пациента проперти - оценка доктору.
14. Когда доктор вам назначает лечение некоторые пациенты должны стать недовольны.
15. В конце дня после того как все лечение будет сделано и доктор напишет рапорт, надо пройтись по пациентам и всем недовольным поменять доктора.
16. Начать новый день и убедиться что Недовольные пациенты таки поменяли доктора.


Выполнил все задания (ученик, студент, мастер, супермен).
Файлы проекта с домашним заданием.

Вывод работы программы на экран получился такой:

 2015-08-06 09:44:42.539 DZ9Delegates[1757:41250] DAY 1
2015-08-06 09:44:42.540 DZ9Delegates[1757:41250] My name is Vasya. My health worsened, temperature: 39.5. I call the medic.
2015-08-06 09:44:42.540 DZ9Delegates[1757:41250] Patient Vasya temperature: 39.5 Ache: Head Ache. Treat headache
2015-08-06 09:44:42.540 DZ9Delegates[1757:41250] Vasya treat. Rating doctor: 2
2015-08-06 09:44:42.540 DZ9Delegates[1757:41250] My name is Kolya. My health worsened, temperature: 38.5. I call the medic.
2015-08-06 09:44:42.540 DZ9Delegates[1757:41250] Patient Kolya temperature: 38.5 Ache: Stomach stomachache. Treat Heartache
2015-08-06 09:44:42.540 DZ9Delegates[1757:41250] Kolya treat. Rating doctor: 1
2015-08-06 09:44:42.541 DZ9Delegates[1757:41250] My name is Dima. My health worsened, temperature: 40.5. I call the medic.
2015-08-06 09:44:42.541 DZ9Delegates[1757:41250] My friend Dima Ache: ToothAche Ache. Drink vodka shot
2015-08-06 09:44:42.541 DZ9Delegates[1757:41250] Dima treat. Rating doctor: 5
2015-08-06 09:44:42.541 DZ9Delegates[1757:41250] My name is Natasha. My health worsened, temperature: 37. I call the medic.
2015-08-06 09:44:42.625 DZ9Delegates[1757:41250] My friend Natasha Ache: Head heartache. Drink vodka shot
2015-08-06 09:44:42.626 DZ9Delegates[1757:41250] Natasha treat. Rating doctor: 4
2015-08-06 09:44:42.626 DZ9Delegates[1757:41250] My name is Denis. My health worsened, temperature: 36. I call the medic.
2015-08-06 09:44:42.626 DZ9Delegates[1757:41250] Patient Denis temperature: 36 Ache: Head Ache. Treat headache
2015-08-06 09:44:42.626 DZ9Delegates[1757:41250] Denis treat. Rating doctor: 4
2015-08-06 09:44:42.626 DZ9Delegates[1757:41250] List patient with Head Ache:   Vasya     Denis  
2015-08-06 09:44:42.626 DZ9Delegates[1757:41250] List patient with Stomach Ache:   Kolya  
2015-08-06 09:44:42.626 DZ9Delegates[1757:41250] Patient Vasya change Doctor
2015-08-06 09:44:42.627 DZ9Delegates[1757:41250] Patient Kolya change Doctor
2015-08-06 09:44:42.627 DZ9Delegates[1757:41250] DAY 2
2015-08-06 09:44:42.627 DZ9Delegates[1757:41250] My name is Vasya. My health worsened, temperature: 39.5. I call the medic.
2015-08-06 09:44:42.627 DZ9Delegates[1757:41250] My friend Vasya Ache: Head Ache. Drink vodka shot
2015-08-06 09:44:42.627 DZ9Delegates[1757:41250] Vasya treat. Rating doctor: 3
2015-08-06 09:44:42.627 DZ9Delegates[1757:41250] My name is Kolya. My health worsened, temperature: 38.5. I call the medic.
2015-08-06 09:44:42.627 DZ9Delegates[1757:41250] My friend Kolya Ache: Other Ache. Drink vodka shot
2015-08-06 09:44:42.628 DZ9Delegates[1757:41250] Kolya treat. Rating doctor: 4
2015-08-06 09:44:42.628 DZ9Delegates[1757:41250] My name is Dima. My health worsened, temperature: 40.5. I call the medic.
2015-08-06 09:44:42.628 DZ9Delegates[1757:41250] My friend Dima Ache: ToothAche Ache. Drink vodka shot
2015-08-06 09:44:42.629 DZ9Delegates[1757:41250] Dima treat. Rating doctor: 5
2015-08-06 09:44:42.629 DZ9Delegates[1757:41250] My name is Natasha. My health worsened, temperature: 37. I call the medic.
2015-08-06 09:44:42.629 DZ9Delegates[1757:41250] My friend Natasha Ache: Head heartache. Drink vodka shot
2015-08-06 09:44:42.629 DZ9Delegates[1757:41250] Natasha treat. Rating doctor: 1
2015-08-06 09:44:42.629 DZ9Delegates[1757:41250] My name is Denis. My health worsened, temperature: 36. I call the medic.
2015-08-06 09:44:42.629 DZ9Delegates[1757:41250] Patient Denis temperature: 36 Ache: Head Ache. Treat headache
2015-08-06 09:44:42.629 DZ9Delegates[1757:41250] Denis treat. Rating doctor: 1