Я просто думал, поскольку можно рассматривать Блоки как объекты, если я создаю двух из них и затем добавляю их к NSArray, там способ выполнить их от массива?
int (^Block_001)(void) = ^{ return 101; };
int (^Block_002)(void) = ^{ return 202; };
NSArray *array = [NSArray arrayWithObjects:Block_001, Block_002, nil];
Править: Обновление для ясности На превосходный ответ @davedelong
int (^Block_001)(void) = [^{ return 101; } copy];
int (^Block_002)(void) = [^{ return 202; } copy];
NSArray *array = [NSArray arrayWithObjects:Block_001, Block_002, nil];
[Block_001 release];
[Block_002 release];
Конечно, вы просто вызываете его с помощью ()
, как и любой другой блок, но вам нужно привести значение, полученное из NSArray
. Вот пример (с добавленным typedef, потому что в противном случае у меня болит голова):
typedef int (^IntBlock)(void);
IntBlock Block_001 = ^{ return 101; };
IntBlock Block_002 = ^{ return 202; };
NSArray *array = [NSArray arrayWithObjects:Block_001, Block_002, nil];
int x = ((IntBlock)[array objectAtIndex:0]) (); // now x == 101
Конечно, можете.
int (^x)(void) = [array objectAtIndex:0];
printf("%d\n", x()); // prints 101.
@KennyTM и @David правы, но ваш код потенциально неверен. Вот почему:
При создании NSArray
с объектами, он будет сохранять
объекты, помещенные в него. В случае с блоками для этого используется функция Block_retain
. Это означает, что массив сохранил созданные вами блоки, но которые живут на стеке (блоки - один из очень редких примеров объектов Objective-C, которые можно создавать на стеке, не прибегая к абсурдным ухищрениям). Это означает, что после выхода из этого метода ваш массив теперь указывает на мусор, потому что блоки, на которые он указывал больше не существуют. Чтобы сделать это правильно, вы должны сделать следующее:
int (^Block_001)(void) = [^{ return 101; } copy];
int (^Block_002)(void) = [^{ return 202; } copy];
NSArray *array = [NSArray arrayWithObjects:Block_001, Block_002, nil];
[Block_001 release];
[Block_002 release];
Вызывая copy
для блока, вы явно перемещаете блок из стека в кучу, где он может безопасно оставаться после выхода метода/функции. Затем, после того как вы добавили блоки в массив, вам нужно сбалансировать copy
(из-за правила NARC) последующим вызовом release
. Имеет смысл?