为什么 typedef 一个块而不是使用一个普通的块?
Why typedef a block instead of using a normal one?
在此 project、ArrayDataSource
中 class 有一个 public 方法使用 typedef-ing 块作为参数:
来源是这样的:
//ArrayDataSource.h
typedef void (^TableViewCellConfigureBlock)(id cell, id item);
- (id)initWithItems:(NSArray *)anItems
cellIdentifier:(NSString *)aCellIdentifier
configureCellBlock:(TableViewCellConfigureBlock)aConfigureCellBlock;
//ArrayDataSource.m
@property (nonatomic, copy) TableViewCellConfigureBlock configureCellBlock;
- (id)initWithItems:(NSArray *)anItems
cellIdentifier:(NSString *)aCellIdentifier
configureCellBlock:(TableViewCellConfigureBlock)aConfigureCellBlock
{
self = [super init];
if (self) {
self.items = anItems;
self.cellIdentifier = aCellIdentifier;
self.configureCellBlock = [aConfigureCellBlock copy];
}
return self;
}
为什么不成功:
//ArrayDataSource.h
//no typedef
- (id)initWithItems:(NSArray *)anItems
cellIdentifier:(NSString *)aCellIdentifier
configureCellBlock:(void(^)(id cell, id item))aConfigureCellBlock;
//ArrayDataSource.m:
@property (nonatomic, copy) void*(^configBlock)(id cell, id item);
- (id)initWithItems:(NSArray *)anItems cellIdentifier:(NSString *)aCellIdentifier configureCellBlock:(void (^)(id, id))aConfigureCellBlock{
self = [super init];
if (self) {
self.items = anItems;
self.cellIdentifier = aCellIdentifier;
self.configBlock = [aConfigureCellBlock copy];
}
return self;
}
这样做有什么好处吗?
块语法不是 Objective-C 风格...
使用 typedef
让你的代码更漂亮。
它还允许您在许多情况下重复使用相同的块类型。
(如果你会考虑服务器请求块,并且许多请求方法每个都有相同的响应块作为参数,使用 typedef 将防止代码重用......)
typedef
ing 块背后的整个想法是让 ObjC 看起来更干净、更好看。如果你有这样的块:
NSMutableAttributedString *(^)(UIFont *, UIColor *, const CGFloat, NSString *)
如果将其作为参数,您会得到一个难以阅读的巨大混乱。如果你 typedef
它,它会变得更好,因为你只传递 typedef
名称。而且如果你把它命名为AttributedStringAssemblerBlock
,它也更容易理解。
块的问题在于它们对 ObjC 来说是相当新的,并且没有正确的外观和感觉。 swift 中的闭包要好得多,并且更适合该语言。
第二件事是评论中指出的重用。为块使用通用类型定义使它们可以在任何地方重复使用。
在此 project、ArrayDataSource
中 class 有一个 public 方法使用 typedef-ing 块作为参数:
来源是这样的:
//ArrayDataSource.h
typedef void (^TableViewCellConfigureBlock)(id cell, id item);
- (id)initWithItems:(NSArray *)anItems
cellIdentifier:(NSString *)aCellIdentifier
configureCellBlock:(TableViewCellConfigureBlock)aConfigureCellBlock;
//ArrayDataSource.m
@property (nonatomic, copy) TableViewCellConfigureBlock configureCellBlock;
- (id)initWithItems:(NSArray *)anItems
cellIdentifier:(NSString *)aCellIdentifier
configureCellBlock:(TableViewCellConfigureBlock)aConfigureCellBlock
{
self = [super init];
if (self) {
self.items = anItems;
self.cellIdentifier = aCellIdentifier;
self.configureCellBlock = [aConfigureCellBlock copy];
}
return self;
}
为什么不成功:
//ArrayDataSource.h
//no typedef
- (id)initWithItems:(NSArray *)anItems
cellIdentifier:(NSString *)aCellIdentifier
configureCellBlock:(void(^)(id cell, id item))aConfigureCellBlock;
//ArrayDataSource.m:
@property (nonatomic, copy) void*(^configBlock)(id cell, id item);
- (id)initWithItems:(NSArray *)anItems cellIdentifier:(NSString *)aCellIdentifier configureCellBlock:(void (^)(id, id))aConfigureCellBlock{
self = [super init];
if (self) {
self.items = anItems;
self.cellIdentifier = aCellIdentifier;
self.configBlock = [aConfigureCellBlock copy];
}
return self;
}
这样做有什么好处吗?
块语法不是 Objective-C 风格...
使用 typedef
让你的代码更漂亮。
它还允许您在许多情况下重复使用相同的块类型。 (如果你会考虑服务器请求块,并且许多请求方法每个都有相同的响应块作为参数,使用 typedef 将防止代码重用......)
typedef
ing 块背后的整个想法是让 ObjC 看起来更干净、更好看。如果你有这样的块:
NSMutableAttributedString *(^)(UIFont *, UIColor *, const CGFloat, NSString *)
如果将其作为参数,您会得到一个难以阅读的巨大混乱。如果你 typedef
它,它会变得更好,因为你只传递 typedef
名称。而且如果你把它命名为AttributedStringAssemblerBlock
,它也更容易理解。
块的问题在于它们对 ObjC 来说是相当新的,并且没有正确的外观和感觉。 swift 中的闭包要好得多,并且更适合该语言。
第二件事是评论中指出的重用。为块使用通用类型定义使它们可以在任何地方重复使用。