Ответ 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
}
}