Подтвердить что ты не робот

Копирование блоков (например: копирование их в переменные экземпляра) в Objective-C

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

Руководство по программированию блоков заставляет его звучать так, как я могу это сделать, используя Block_copy/сохранить, чтобы скопировать блок, но когда я пытаюсь запустить его, я разбиваю свою программу.

- (void) setupStoredBlock
{
    int salt = 42;
    m_storedBlock = ^(int incoming){ return 2 + incoming + salt; };
    [m_storedBlock retain];
}

Я пытаюсь называть его позже:

- (void) runStoredBlock
{
    int outputValue = m_storedBlock(5);
    NSLog(@"When we ran our stored blockwe got back: %d", outputValue);
    [m_storedBlock release];
}

У кого-нибудь есть идеи? (Или, что-то я не получаю с блоками?)

Большое спасибо!

4b9b3361

Ответ 1

Вместо этого вы захотите сделать это:

- (void) setupStoredBlock
{
    int salt = 42;
    m_storedBlock = Block_copy(^(int incoming){ return 2 + incoming + salt; });
}

Ответ 2

Скопируйте блок, когда вы хотите, чтобы он оставался. Autorelease или отпустите его, когда вы закончите с ним. Сохраните его, если вам понадобится длинный путь для написания /* NOP */.

@interface Foo : FooSuper {}
@property(copy) int (^storedBlock)(int);
@end

@implementation Foo
@synthesize storedBlock = mStoredBlock;

- (void)setupStoredBlock {
    self.storedBlock = ^{/*...*/};
    // or: mStoredBlock = [^{/*...*/} copy];
    // but this simple implementation violates the atomicity contract
}

- (void)runStoredBlock {
    int result = self.storedBlock(5);
    NSLog(@"%s: result = %d", __func__, result);
}
@end

Ответ 3

• Как и все локальные переменные, в стеке существует нестатический блок и будет выгружаться из стека, как и любая другая локальная переменная, которая не была объявлена ​​статической.

• Block_copy() копирует блок из стека в кучу, где все экземпляры malloc существуют. И, как и все новые методы /copy, Block_copy() возвращает объект с выделенной кучей с номером сохранения 1. Блок является объектом objectC, но не соответствует как обычный объект. Следовательно, не должно быть разницы между Block_Release() и методом объектной разблокировки.

• В этом примере используется метод копирования экземпляра блока. Поскольку для присвоения результата Block_copy() для идентификатора требуется тип, который я делаю. Не хочу ошибаться. Метод копирования позволяет блок-переменной присваиваться непосредственно идентификатору.

 - (void) setupStoredBlock
{
    int zStackLocalVariable = 42;
    iHeapAllocatedVariable = [^int(int aMore){ return zStackLocalVariable + aMore; } copy];
}

• Чтобы объявить объект static, требуется, чтобы он был физически выделен самим кодом. Блоком, который объявляется статичным, является компилятор, которому запрещен доступ к переменным за пределами его собственной области. Из-за требований объявления статического блока я предполагаю, что блок в стеке каким-то образом отличается от блока, который находится в куче.

• Блок - объективный объект c, класс которого, чье имя класса и другая связанная информация я еще не пытался извлечь, но, как и объекты Protocol, Object и другие скрытые классы objectC, он не соответствует NSObject. Однако, как и все объекты objectC, он должен соответствовать сохранению/освобождению. ARC расширяет эквиваленты сохранения/освобождения в объектах Core Foundation и, возможно, если не сейчас, то в конечном итоге, в malloc/free allocations.

• Я жду настоящей мотивации для тщательного изучения mikeash.com, так как яблоко любит держать нас всех на некоторых гипер-теоретических плоскости небольшого физического значения, хотя все, что имеет значение, является физическим.

ARC и блоки также обсуждаются здесь

Ответ 4

В недавнем WWDC (2010) была очень приятная презентация по этому вопросу. В нем описано, как были реализованы блоки и почему вам нужно использовать Block_copy. Вы можете скачать фильм из презентации: http://developer.apple.com/itunes/?destination=adc.apple.com.4092414566 Фильм называется "Расширенный Objective-C и сбор мусора"