Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Objective-C

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
Dev_Dev
0 / 0 / 0
Регистрация: 11.11.2012
Сообщений: 69
#1

Отличия блоков от обычных функций - Objective-C

11.11.2014, 17:52. Просмотров 1349. Ответов 4
Метки нет (Все метки)

Здравствуйте, вот пришлось столкнуться с блоками. Вопрос в том, чем они отличаются от обычных функций. Например:

Objective-C
1
2
3
4
5
6
7
8
 
__block CGFloat result = 0;
   NSArray *array = [NSArray init...]      // init with something
    [array enumerateObjectsUsingBlock:^(NSNumber *weight, NSUInteger idx, BOOL *stop) {
        if (idx == inputs.count) {
            *stop = YES;
            return;
        }
В википедии написано, что в "в отличие от обычных функций, значения переменных в блоке могут устанавливаться из окружающего констекста ". Но можно создать обычную функцию, в которую также передать в качестве входных параметров локальные переменные. Тогда в чем разница?????? Может кто-нибудь простым языком объяснить?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.11.2014, 17:52
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Отличия блоков от обычных функций (Objective-C):

Отличия методов класса от обычных функций - C++
Что собой представляет метод в классах? Это такое же как и простая функция или что-то другое? Можно простой пример привести какая разница...

Отличия процедур и функций - Delphi
скажите плз что такое процедуры и функции, и чем они отличаются

Отличия вызова анонимной и именованной функций. - jQuery
Что то понять не могу, что не так... В общем если так, то работает $(window).resize(function(){ ...

Написать набор функций, обслуживающих блочно-диагональные матрицы из нескольких нижне-треугольных блоков - C++
Написать набор функций (create,access,destroy), обслуживающих блочно-диагональные матрицы из нескольких нижне-треугольных блоков порядка...

Замена обычных названий - C#
Вот и на такое наткнулся... Учитель просит перед названием каждого элемента того или иного типа ставить 3-4 буквенное сокращение... К...

Решение обычных примеров - C (СИ)
Написал такой код но выдает ошибку на строке где комментарий. Не могу понять в чем дела помогите пожалуйста #include<conio.h> ...

4
Vorona
Peace 2 all shining faces
669 / 531 / 45
Регистрация: 05.03.2010
Сообщений: 1,283
11.11.2014, 22:37 #2
блоки в objective-c, грубо говоря, служат в качестве анонимных функций, лямбда выражений или замыканий
если знаете ruby, javascript или например python, то вы уже знаете что это

блоки можно присваивать переменным, передавать в функции и возвращать из функций
в более функциональных языках функции изначально являются функциями высшего порядка или функциями первого класса
В objective-c это немного затянуто и иначе реализовано, потому на помощь приходят блоки, вот и все

намного удобней написать вот так
Objective-C
1
2
3
4
5
6
[array enumerateObjectsUsingBlock:^(NSNumber *weight, NSUInteger idx, BOOL *stop) {
    if (idx == inputs.count) {
        *stop = YES;
        return;
    }
}];
нежели как-то так:
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@interface MyClass <NSArrayEnumerator>
 
// . . .
 
- (void)myMethod
{
    [array enumerateObjectsWithDelegate:self]
}
 
// . . .
 
- (void)array:(NSArray *)array enumerateNextWithWeight:(NSNumber *)weight index:(NSUInteger)idx stop:(BOOL *)stop
{
    if (idx == inputs.count) {
        *stop = YES;
        return;
    }
}
Конечно, пример не из реальной жизни, но к сожалению очень часто именно так и происходит, и что еще хуже,
так то, что "старые фанаты" делегатов не понимают и не хотят учиться не хотят использовать блоки и пишут подобную ерунду
1
Dev_Dev
0 / 0 / 0
Регистрация: 11.11.2012
Сообщений: 69
12.11.2014, 01:08  [ТС] #3
Мне Java и Python не знакомы. Я больше С/С++ и Objective-C. Ну вот смотрите, я приведу 2 примера. Перемножаем два одномерных массива:
Objective-C
1
2
3
4
5
6
7
8
9
10
__block NSMutableArray *result = [[NSMutableArray alloc] init];
 NSArray *array1 = [[NSArray alloc] initWithObjects:@1, @1, nil]; 
 NSArray *array2 = [[NSArray alloc] initWithObjects:@2, @3, nil ];
    [array1 enumerateObjectsUsingBlock:^(NSNumber *element, NSUInteger idx, BOOL *stop) {
        if (idx == array1.count) {
            *stop = YES;
            return;
        }
    [result addObject:element*array2[idx]];
}
И вот другой пример перемножения массивов
Objective-C
1
2
3
4
5
6
7
8
NSMutableArray *result = [[NSMutableArray alloc] init];
 NSArray *array1 = [[NSArray alloc] initWithObjects:@1, @1, nil]; 
 NSArray *array2 = [[NSArray alloc] initWithObjects:@2, @3, nil ];
 
for(int i = 0; i < array1.count; i++)
{
[result addObject:array1[i]*array2[i]];
}
В обоих случаях получаем один и тот же массив. Вот в данном примере, где разница? Спасибо большое ! )))
0
Xavier
in god we trust
74 / 74 / 8
Регистрация: 20.04.2012
Сообщений: 201
12.11.2014, 09:45 #4
В данном конкретном примере с массивами все зависит от того что тебе надо. Во первых лучше все же использовать for in loop для коллекций, компилятор немного оптимизирует его и код выполняется чуток быстрее чем простое for. Enumirate в свою очередь выполняется или по крайней мере пытается выполнить итерацию еще быстрее используя для этого NSFastEnumiration. В данном примере можно использовать и тот и тот способ, повторюсь все зависит от того что именно надо.

А реальную помощь блоки приносят в тех же колбеках (complition handler). Например тот же sendAsynchronousRequest:queue:completionHandler: метод у NSURLConnection гораздо удобнее встроить блок "по ходу", чем писать различные функции, так как реквесты могут быть разные и данные соответсвенно отличаются, то и обрабатывать их нужно по разному. Я надеюсь понятно.
Вообще тот же GCD весь основан на блоках.

Блоки мощная штука, но там есть и свои подводные камни, соответсвенно использовать их нужно внимательно и осторожно.
1
Vorona
Peace 2 all shining faces
669 / 531 / 45
Регистрация: 05.03.2010
Сообщений: 1,283
12.11.2014, 23:39 #5
вообще, желательно посмотреть в сторону декларативного и функционального программирования для упрощения жизни и кода
например, вместо, того, чтобы умножать два массива посредством форича, слежением за индексом и размерами обеих массивов, можно было бы использовать простую безопасную функцию zipWith
в Haskell ее можно использовать так
Haskell
1
zipWith (*) [1,2,3] [2,3,4]
в Objective-C это можно было бы легко сделать при помощи блоков
Objective-C
1
2
3
zipWith(array1, array2, ^NSNumber *(NSNumber *obj1, NSNumber *obj2) {
    return @(obj1.integerValue * obj2.integerValue);
});
На выходе получаем массив перемноженных объектов, длина которого будет равна длине более "короткого" массива, потому не стоит ни о чем беспокоиться
плюс насчет безопасности и чистоты этой функции - она не меняет ни один из входных массивов, а наоборот отдает просто результат операций над ними, что позволяет поддержать чистоту кода и убирает проблему путаницы с состояниями.

Вот Underscore.m - отличный пример использования блоков в "бытовухе", ну и конечно, не говоря уже об колбеках ответов с сервера и т.д. как выше упомянул Xavier
1
12.11.2014, 23:39
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.11.2014, 23:39
Привет! Вот еще темы с ответами:

Сортировка чисел, но не обычных! ->> - Delphi
Приветствую. Перед созданием темы пользовался поиском, но так и не нашел нужную мне тему. Если дубль, то прошу послать к нужной теме...

Отбор в обычных формах - 1С
В управляемых формах есть &quot;Связи параметров выбора&quot; чтобы можно было выбирать из значений для которых определенное значение является...

Калькулятор обычных дробей Delphi7 - Delphi
Всем привет! Задание: Создание калькулятора, действия с обычными дробями. Я сделал (+,-,*,/), надо еще возведение в целую...

Инициализация обычных статических переменных - Java SE
Добрый вечер. Читаю небезызвестную философию джава. В одной из глав есть пример о порядке иницыализации статических и обычных полей. Код...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru