Objective-C传递块作为参数
我怎样才能通过一个Function / Method Block ? 
 我试过- (void)someFunc:(__Block)someBlock无济于事。 
 即。 什么是一个Block的types ? 
 块的types取决于其参数和返回types。 在一般情况下,块types被声明为函数指针types的相同方式,但用^replace* 。 将块传递给方法的一种方法如下所示: 
 - (void)iterateWidgets:(void (^)(id, int))iteratorBlock; 
 但是,正如你所看到的,那很乱。 您可以改为使用typedef来使块types更清洁: 
 typedef void (^ IteratorBlock)(id, int); 
然后将该块传递给如下所示的方法:
 - (void)iterateWidgets:(IteratorBlock)iteratorBlock; 
这可能有帮助:
 - (void)someFunc:(void(^)(void))someBlock; 
这个问题的最简单的解释是遵循这些模板:
1.作为方法参数的块
模板
 - (void)aMethodWithBlock:(returnType (^)(parameters))blockName { // your code } 
例
 -(void) saveWithCompletionBlock: (void (^)(NSArray *elements, NSError *error))completionBlock{ // your code } 
其他使用情况:
2.作为一个财产封锁
模板
 @property (nonatomic, copy) returnType (^blockName)(parameters); 
例
 @property (nonatomic,copy)void (^completionBlock)(NSArray *array, NSError *error); 
3.阻止作为方法的参数
模板
 [anObject aMethodWithBlock: ^returnType (parameters) { // your code }]; 
例
 [self saveWithCompletionBlock:^(NSArray *array, NSError *error) { // your code }]; 
4.作为局部variables阻止
模板
 returnType (^blockName)(parameters) = ^returnType(parameters) { // your code }; 
例
 void (^completionBlock) (NSArray *array, NSError *error) = ^void(NSArray *array, NSError *error){ // your code }; 
5.作为一个typedef块
模板
 typedef returnType (^typeName)(parameters); typeName blockName = ^(parameters) { // your code } 
例
 typedef void(^completionBlock)(NSArray *array, NSError *error); completionBlock didComplete = ^(NSArray *array, NSError *error){ // your code }; 
你可以这样做,传递块作为块参数:
 //creating a block named "completion" that will take no arguments and will return void void(^completion)() = ^() { NSLog(@"bbb"); }; //creating a block namd "block" that will take a block as argument and will return void void(^block)(void(^completion)()) = ^(void(^completion)()) { NSLog(@"aaa"); completion(); }; //invoking block "block" with block "completion" as argument block(completion); 
如果适用于您,也可以将块设置为简单属性:
 @property (nonatomic, copy) void (^didFinishEditingHandler)(float rating, NSString *reviewString); 
确保块属性是“复制”!
当然你也可以使用typedef:
 typedef void (^SimpleBlock)(id); @property (nonatomic, copy) SimpleBlock someActionHandler; 
在下面的例子中使用с函数传递块的另一种方法。 我创build了在后台和主队列中执行任何操作的函数。
blocks.h文件
 void performInBackground(void(^block)(void)); void performOnMainQueue(void(^block)(void)); 
blocks.m文件
 #import "blocks.h" void performInBackground(void(^block)(void)) { if (nil == block) { return; } dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), block); } void performOnMainQueue(void(^block)(void)) { if (nil == block) { return; } dispatch_async(dispatch_get_main_queue(), block); } 
在必要时导入blocks.h并调用它:
 - (void)loadInBackground { performInBackground(^{ NSLog(@"Loading something in background"); //loading code performOnMainQueue(^{ //completion hadler code on main queue }); }); } 
你也可以使用通常的c函数语法调用或调用一个块
 -(void)iterateWidgets:(IteratorBlock)iteratorBlock{ iteratorBlock(someId, someInt); } 
更多信息块在这里
尽pipe在这个线程上给出的答案,我真的很努力编写一个函数,将一个块作为一个函数 – 和一个参数。 最终,这是我提出的解决scheme。
 我想写一个通用函数loadJSONthread ,它将采用JSON Web服务的URL,从后台线程的URL中加载一些JSON数据,然后将NSArray *的结果返回给调用函数。 
基本上,我想把所有的后台线程复杂性隐藏在一个通用的可重用函数中。
以下是我将如何调用这个函数:
 NSString* WebServiceURL = @"http://www.inorthwind.com/Service1.svc/getAllCustomers"; [JSONHelper loadJSONthread:WebServiceURL onLoadedData:^(NSArray *results) { // Finished loading the JSON data NSLog(@"Loaded %lu rows.", (unsigned long)results.count); // Iterate through our array of Company records, and create/update the records in our SQLite database for (NSDictionary *oneCompany in results) { // Do something with this Company record (eg store it in our SQLite database) } } ]; 
  …这就是我所苦苦挣扎的一点:如何声明它,以及如何在数据加载完成后调用Block函数,并通过Block加载的NSArray *logging: 
 +(void)loadJSONthread:(NSString*)urlString onLoadedData:(void (^)(NSArray*))onLoadedData { __block NSArray* results = nil; dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^{ // Call an external function to load the JSON data NSDictionary * dictionary = [JSONHelper loadJSONDataFromURL:urlString]; results = [dictionary objectForKey:@"Results"]; dispatch_async(dispatch_get_main_queue(), ^{ // This code gets run on the main thread when the JSON has loaded onLoadedData(results); }); }); } 
 这个StackOverflow问题涉及如何调用函数,传递一个Block作为参数,所以我简化了上面的代码,并没有包含loadJSONDataFromURL函数。 
但是,如果你有兴趣,你可以在这个博客上find这个JSON加载函数的副本: http : //mikesknowledgebase.azurewebsites.net/pages/Services/WebServices-Page6.htm
希望这有助于其他XCode开发人员! (不要忘记把这个问题和我的答案投票,如果是的话)!
我总是倾向于忘记块语法。 当我需要声明一个块的时候,这总是出现在我的脑海里。 我希望它可以帮助别人:)
我给一个类写了一个completionBlock,这个类会在被撼动后返回骰子的值:
- 
使用returnType定义typedef(在 @interface声明之上的.h)typedef void (^CompleteDiceRolling)(NSInteger diceValue);
- 
为块( .h)定义@property@property (copy, nonatomic) CompleteDiceRolling completeDiceRolling;
- 
用 finishBlock(.h)定义一个方法- (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock;
- 
将以前定义的方法插入到 .m文件中,@propertyfinishBlock提交给之前定义的finishBlock- (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock{ self.completeDiceRolling = finishBlock; }
- 
触发 completionBlock将预定义的variableType传递给它(不要忘记检查completionBlock是否存在)if( self.completeDiceRolling ){ self.completeDiceRolling(self.dieValue); }