Objective-C传递块作为参数

我怎样才能通过一个Function / Method Block

我试过- (void)someFunc:(__Block)someBlock无济于事。

即。 什么是一个Blocktypes

块的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); } 

更多信息块在这里

http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/bxGettingStarted.html#//apple_ref/doc/uid/TP40007502-CH7-SW1

尽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开发人员! (不要忘记把这个问题和我的答案投票,如果是的话)!

我总是倾向于忘记块语法。 当我需要声明一个块的时候,这总是出现在我的脑海里。 我希望它可以帮助别人:)

http://fuckingblocksyntax.com

我给一个类写了一个completionBlock,这个类会在被撼动后返回骰子的值:

  1. 使用returnType定义typedef(在@interface声明之上的.h

     typedef void (^CompleteDiceRolling)(NSInteger diceValue); 
  2. 为块( .h )定义@property

     @property (copy, nonatomic) CompleteDiceRolling completeDiceRolling; 
  3. finishBlock.h )定义一个方法

     - (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock; 
  4. 将以前定义的方法插入到.m文件中, @property finishBlock提交给之前定义的finishBlock

     - (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock{ self.completeDiceRolling = finishBlock; } 
  5. 触发completionBlock将预定义的variableType传递给它(不要忘记检查completionBlock是否存在)

     if( self.completeDiceRolling ){ self.completeDiceRolling(self.dieValue); }