Просто пытаюсь разобраться с блоками. Я понял концепцию. Они похожи на указатели на функции, но на самом деле являются объектами; вы можете объявить блочную переменную и присвоить ей блочное значение; назовите это как функцию; они «замораживаются во времени» из-за отсутствия термина, когда они выполняются и т. д. Я создал несколько блоков и успешно запустил их в нескольких разных форматах, но когда дело доходит до их использования в методе --либо с typedef, либо без --У меня большие проблемы. Например, вот объектный интерфейс, который я создал, просто чтобы понять синтаксис. Я почти не представляю, как это реализовать.
// AnObject.h
#import <Foundation/Foundation.h>
// The idea with the block and the method below is for the block to take
// an int, multiply it by 3, and return a "tripled" int. The method
// will then repeat: this process however many times the user wants via
// the howManyTimes parameter and return that value in the form of an int.
typedef int (^triple)(int);
@interface AnObject : NSObject
{
int num;
}
-(int)repeat:(int)howManyTimes withBlock:(triple)someBlock;
@end
Вот что у меня есть для реализации на данный момент:
#import "AnObject.h"
@implementation AnObject
@synthesize num;
-(int)repeat:(int)howManyTimes withBlock:(triple)someBlock {
for (int i = 0; i <= howManyTimes; i++) {
// What the heck am I supposed to put here? I'm baffled by the
// syntax over and over again.
}
}
@end
Я знаю, что пока не обращаюсь к переменной экземпляра. Опять же, это черновик, просто попытка понять, как работают блоки. Я даже правильно объявляю этот метод? Я читаю книгу Big Nerd Ranch Objective -C Programming, статью Майка Кларка о блоках из Pragmatic Studio и несколько потоков SO. Не могу найти ничего подходящего. Спасибо.
РЕДАКТИРОВАТЬ :XCode 4.3.2, если это имеет значение.
ДОПОЛНИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ :Хорошо. Используя слегка модифицированный )пример BJ (, я думаю, что нашел действительно сложный способ умножения 5 на 3.:)
// BJ's implementation:
-(int)repeat:(int)howManyTimes withBlock:(Triple)someBlock {
int blockReturnValue;
for (int i = 0; i <= howManyTimes; i++) {
blockReturnValue = someBlock(i);
}
return blockReturnValue;
}
Main:
...
@autoreleasepool
{
AnObject *obj = [[AnObject alloc] init];
NSLog(@"%d", [obj repeat: 5 withBlock: ^ (int number) {
return number * 3;
}]);
}
return 0;
...
И выход:
15
Теперь, это откидывается назад 15, потому что блок, который я определил как аргумент, запускается только один раз, верно? Он умножает «число», которое в данном случае равно 5,на 3 и замораживает этот ответ, верно? Я уверен, что только что создал совершенно бесполезный метод, и я еще не понимаю, как использовать преимущества/функции блока. Я прав?
/*********************ОБНОВЛЕНИЕ*********************/
ОБНОВЛЕНИЕ :Я понимаю, о чем вы говорите, CRD. Просто исправление, однако, для любых новых программистов, которые могут читать это, получать другой вывод и говорить «Que?» Ваш цикл for должен быть либо:
for (int i = 0; i < howManyTimes; i++)
value = someBlock(value);
...или...
(i = 1; i <= howManyTimes; i++)
...чтобы получить ответ 243.
И, да, это именно то, что я изначально пытался сделать с этим кодом. По крайней мере, я думал, что это должно было произойти. Оказывается, намерением автора было не утроить число, сохранить это значение, утроить сохраненное значение, сохранить это... и т. д., а просто напечатать x *3 для чисел 1 -5 (3, 6, 9, 12, 15 ).
Вот и готовый продукт. Я только что набрал блок, который принимает целое число и возвращает целое число, под названием Tripler. Я также изменил имя аргумента с «someBlock» на «triple», чтобы более четко указать предполагаемое использование блока. Я думаю, что это единственные изменения в коде.
/******************** interface ********************/
#import <Foundation/Foundation.h>
typedef int (^Tripler)(int);
@interface AnObject : NSObject
-(void)iterateFromOneTo:(int)number withBlock:(Tripler)triple;
@end
/******************** implementation ********************/
#import "AnObject.h"
@implementation AnObject
-(void)iterateFromOneTo:(int)number withBlock:(Tripler)triple {
for (int i = 1; i <= number; i++) {
NSLog(@"%d", triple(i));
}
}
@end
/******************** main.m ********************/
#import "AnObject.h"
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
@autoreleasepool
{
AnObject *obj = [[AnObject alloc] init];
[obj iterateFromOneTo:5 withBlock:^(int number) {
return number * 3;
}];
}
return 0;
}
Как вы, вероятно, можете себе представить, в результате получается:
2012-05-05 17:10:13.418 Untitled 2[71735:707] 3
2012-05-05 17:10:13.445 Untitled 2[71735:707] 6
2012-05-05 17:10:13.446 Untitled 2[71735:707] 9
2012-05-05 17:10:13.446 Untitled 2[71735:707] 12
2012-05-05 17:10:13.447 Untitled 2[71735:707] 15
Я сделал это намного сложнее, чем нужно. Извините, что так плохо объяснил это в ОП. Спасибо за вашу помощь! /нить?:)