typedef void (^RequestProductsCompletionHandler)(BOOL success, NSArray * products);
我很难理解这行代码在.h文件中的作用。
请详细解释
答案 0 :(得分:9)
这是具有名称RequestProductsCompletionHandler
的objective-c block类型的定义,它带有2个参数(BOOL和NSArray)并且没有返回值。您可以像调用c函数一样调用它,例如:
RequestProductsCompletionHandler handler = ^(BOOL success, NSArray * products){
if (success){
// Process results
}
else{
// Handle error
}
}
...
handler(YES, array);
答案 1 :(得分:7)
弗拉基米尔描述得很好。它定义了一个变量类型,它将表示将传递两个参数的block,一个布尔success
和一个products
数组,但该块本身返回void
。虽然您不需要使用typedef
,但它会使方法声明更加优雅(并且避免您必须使用复杂的块变量语法)。
为了给你一个实际的例子,可以从块类型的名称及其参数推断出这定义了一个完成块(例如,当一些异步操作(如慢速网络请求)完成时要执行的代码块)。请参阅Using a Block as a Method Argument。
例如,假设您有一些InventoryManager
类,您可以使用typedef
- (void)requestProductsWithName:(NSString *)name completion:(RequestProductsCompletionHandler)completion;
你可以使用这样的方法:
[inventoryManager requestProductsWithName:name completion:^(BOOL success, NSArray * products) {
// when the request completes asynchronously (likely taking a bit of time), this is
// how we want to handle the response when it eventually comes in.
for (Product *product in products) {
NSLog(@"name = %@; qty = %@", product.name, product.quantity);
}
}];
// but this method carries on here while requestProductsWithName runs asynchronously
而且,如果你看一下requestProductsWithName
的实现,可能会看起来像:
- (void)requestProductsWithName:(NSString *)name completion:(RequestProductsCompletionHandler)completion
{
// initiate some asynchronous request, e.g.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// now do some time consuming network request to get the products here
// when all done, we'll dispatch this back to the caller
dispatch_async(dispatch_get_main_queue(), {
if (products)
completion(YES, products); // success = YES, and return the array of products
else
completion(NO, nil); // success = NO, but no products to pass back
});
});
}
显然,这不太可能正是你的特定完成处理程序块正在做的事情,但希望它说明了这个概念。
答案 2 :(得分:2)
Mike Walker创建了一个不错的单页网站,显示了在Objective-C中声明块的所有可能性。这也有助于理解您的问题:
引用他的网站,这就是你如何定义块:
作为本地变量:
returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...};
作为财产:
@property (nonatomic, copy) returnType (^blockName)(parameterTypes);
作为方法参数:
- (void)someMethodThatTakesABlock:(returnType (^)(parameterTypes))blockName {...}
作为方法调用的参数:
[someObject someMethodThatTakesABlock: ^returnType (parameters) {...}];
作为typedef:
typedef returnType (^TypeName)(parameterTypes);
TypeName blockName = ^(parameters) {...}