Попытка понять блоки на iOS
Я пытаюсь понять, как использовать блоки в iOS. Я читал документы Apple, но, как обычно, они расплывчаты и неполны, и несколько существенных бит информации не упоминаются. Я тоже без искажений googled. Это то, что я пытаюсь понять как упражнение, чтобы понять это.
Я создал блок для чтения строки и сравнивает строку с предыдущим чтением. Если строки не совпадают, верните YES, если они совпадают, верните NO.
Вот как я это сделал:
Я объявил это на .h
BOOL (^differentStrings)(void);
Я объявил это на .m, внутри viewDidLoad в viewController
__block NSString * previousString;
__block NSString * currentString;
differentStrings = ^(void){
currentString = [self getString];
NSLog(@"%@", currentString); // not printing anything on console
if (![currentString isEqualToString:previousString]) {
previousString = currentString;
return YES;
} else {
return NO;
}
};
Вот как я использую: у меня есть поток, который делает это:
if (differentStrings)
NSLog (@"strings are different);
Это проблемы, которые у меня есть:
- блок всегда возвращает ДА (строки разные)
- Мне неудобно объявлять об этом внутри videDidLoad. Как мне объявить это, поэтому я могу использовать его глобально как метод? Должен ли я поместить это, как я бы, с помощью метода?
- Я вызываю метод "getString" внутри блока. Все в порядке?
- Мне кажется странным объявлять блок-переменные на .m. Как я вижу, я должен объявить блок-переменные на .h, а затем просто использовать их на .m. Я попытался это сделать, но получил сообщение об ошибке.
- Я установил точку отладки в первой строке блока, но она не останавливается там;
- Строка NSlog внутри блока ничего не печатает. Не называется ли блок?
Можете ли вы, ребята, помочь мне с этим?
Ответы
Ответ 1
Вы не понимаете, как работают блоки. (Хорошо, так что очевидно.) Точно так же, как previousString
- это переменная, указывающая на NSString, differentStrings
- это переменная, указывающая на блок. Не результат работы блока, а скорее сам блок. То есть, после этого:
__block NSString * previousString;
__block NSString * currentString;
differentStrings = ^(void){
currentString = [self getString];
NSLog(@"%@", currentString); // not printing anything on console
if (![currentString isEqualToString:previousString]) {
previousString = currentString;
return YES;
} else {
return NO;
}
};
differentStrings
- это переменная, указывающая на блок. Таким образом, когда вы это делаете:
if (differentStrings)
... вы просто проверяете, содержит ли differentStrings
что-то отличное от 0 или NULL. Поскольку он содержит блок, он не пуст, поэтому он принимает значение true.
Помните: differentStrings
- это блок-переменная, а не переменная BOOL. Он содержит блок (функция, если хотите), который при вызове возвращает bool. Таким образом, чтобы фактически запустить блок, вам нужно вызвать его. Вот так:
differentStrings();
или, в вашем случае:
if (differentStrings()) {
NSLog (@"strings are different");
}
Изменить: Как указано в комментариях, поскольку differentStrings
- это переменная экземпляра, вам нужно copy
это, как вы бы назовёте retain
на любом другом объекте, назначенном к переменной экземпляра. (По техническим причинам я не буду сейчас вдаваться, вы всегда должны использовать copy
с блоками вместо retain
.) Аналогично, вам нужно будет вызвать release
на нем в какой-то момент позже, возможно, в вашем dealloc
.
Ответ 2
Я не верю, что вы на самом деле выполняете блок. Я думаю, что ваш код должен быть
if (differentStrings())
{
NSLog (@"strings are different);
}
Обработать блок как функцию. Я думаю, вы просто проверяли, был ли блок определен, а не выполнял его.
Кроме того, если вам не нужен доступ к NSString за пределами блока, вы можете избавиться от квалификатора __block
и переместить объявление currentString
внутри блока.
Если вам нужен другой ресурс в блоках, я расскажу об этом на осенней сессии моего продвинутого курса развития iOS на iTunes U. Я описываю синтаксис блока в разделе "Поднимание" Cocoa и их использование в Grand Central Dispatch в сеансе многопоточности. Заметки курса также содержат ссылки на некоторые примеры приложений, которые используют блоки по-разному.
Я также не могу рекомендовать достаточно высоко, чтобы вы смотрели видео-сессии WWDC 2010 206 - Знакомство с блоками и Grand Central Dispatch на iPhone и 211 - Упрощение разработки приложений для iPhone с помощью Grand Central Dispatch.
Ответ 3
Я не мог окунуться в блоки, пока не увидел "Блок" и "Mulithreading" из Stanfords Developing Apps для iOS
Ответ 4
Jim Dovey написал замечательную статью о программировании с блоками в блоге iOS: http://ios-blog.co.uk/iphone-development-tutorials/programming-with-blocks-an-overview/
Ответ 5
Ссылка ниже - хорошее введение для блоков
http://www.appcoda.com/objective-c-blocks-tutorial/