Каковы реальные преимущества использования блоков в Objective-C?

Я узнал о блоках в ObjC, синтаксис ясен и прост. Я могу читать "блоки - отличная функция, синтаксис..." почти везде. Однако я скучаю по реальным преимуществам их использования.

Возможно, это глупый вопрос - я только что начал с ObjC, но каковы реальные преимущества блоков над "традиционным" подходом? Может ли кто-нибудь дать мне краткое и ясное объяснение?

Ответ 1

Все, что вы можете делать с блоками, вы можете обойтись без них. Но они обеспечивают отличный способ упростить ваш код и сделать вещи чище. Например, предположим, что у вас есть URL-соединение и вы хотите дождаться результата. Два популярных подхода - обеспечить обратный вызов делегата или использовать блок. В качестве примера я использую фиктивный класс URLConnection.

URLConnection* someConnection = [[[URLConnection alloc] initWithURL:someURL] autorelease];
someConnection.delegate = self;
[someConnection start];

Затем где-то еще в вашем классе

- (void)connection:(URLConnection)connection didFinishWithData:(NSData*)
{
    // Do something with the data
}

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

URLConnection* someConnection = [[[URLConnection alloc] initWithURL:someURL] autorelease];
someConnection.successBlock = ^(NSData*)data {
    // Do something with the data
};
[someConnection start];

Кроме того, скажем, у вас есть несколько подключений в вашем классе, используя один и тот же делегат. Теперь вы должны различать их в методе делегата. Это может осложниться тем, что у вас есть. И с блоком вы можете назначить уникальный блок для каждого URL-соединения.

- (void)connection:(URLConnection)connection didFinishWithData:(NSData*)
{
    if(connection == self.connection1)
    {
        // Do something with the data from connection1
    }
    if(connection == self.connection2)
    {
        // Do something with the data from connection2
    }
    if(connection == self.connection3)
    {
        // Do something with the data from connection3
    }
}

Ответ 2

Определить "традиционный подход"?

Лично лучше видеть блок, так как вы можете видеть, что ответ будет для операции inline и сгруппирован с самой операцией.

"Традиционный" обратный вызов (то, что я предполагаю, что вы имеете в виду), приведет к необходимости прыгать где-нибудь еще в коде, чтобы увидеть, как что-то будет обрабатываться и прыгать назад, а не просто читать все "вместе",.

Ответ 3

Одним из преимуществ блоков является то, что они могут использоваться с NSOperationQueues и Grand Central Dispatch для выполнения параллельных операций более простым и эффективным способом, чем использование NSThread (при условии, что вы используете достаточно новую версию iOS/OS X).

Тот факт, что они могут быть переданы таким образом, что методы не могут сделать их мощной функцией Objective-C.