actionSheet 避开 switch case 写法
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
SEL selectors[] = {
@selector(insertRow),
@selector(insertSection),
@selector(deleteSection)
};
if (buttonIndex < sizeof(selectors) / sizeof(SEL)) {
void(*imp)(id, SEL) = (typeof(imp))[self methodForSelector:selectors[buttonIndex]];
imp(self, selectors[buttonIndex]);
}
}
利用判断条件或者在循环中调用某个方法的方式如上
已知函数名,有两种方式调用函数,之前在 SDWebImage 解析 中总结过可以使用 performSelector 或者 methodForSelector 两个函数。
do {} while(0) 在宏定义中的使用
static void __FD_TEMPLATE_LAYOUT_CELL_PRIMARY_CALL_IF_CRASH_NOT_OUR_BUG__(void (^callout)(void)) {
callout();
}
#define FDPrimaryCall(...) do {__FD_TEMPLATE_LAYOUT_CELL_PRIMARY_CALL_IF_CRASH_NOT_OUR_BUG__(^{__VA_ARGS__});} while(0)
do{} while(0) 构造后宏的定义不会受到大括号、分号等影响。上面的使用方法展示了大括号问题,下面看看分号的影响。
#define foo(x) a(x); b(x)
这段代码本义是调用 foo 函数时指行 a 方法和 b 方法。但是如果你这样使用
if (isTrue)
foo(x);
那么宏扩展后变为
if (isTrue)
a(x);
b(x);
那么改为下面这样呢
#define foo(x) { a(x); b(x); }
扩展后变为
if (isTrue) {
a(x);
b(x);
};
上面的方式又出现语法错误,所以修改为以下方式即可
#define foo(x) do { a(x); a(x); } while (0)
实现 NSCopying 协议限定
- (BOOL)existsHeightForKey:(id<NSCopying>)key;
id
__kindof 返回一个子类实例
- (__kindof UITableViewHeaderFooterView *)fd_templateHeaderFooterViewForReuseIdentifier:(NSString *)identifier {
// ...
}
UITableViewHeaderFooterView *templateHeaderFooterView = [self fd_templateHeaderFooterViewForReuseIdentifier:identifier];
用 __kindof UITableViewHeaderFooterView 替换 id,明确表明了返回值的类型,又不需要调用的时候进行强制转换,只要 templateHeaderFooterView 是 UITableViewHeaderFooterView 的子类即可,不会出现警告,不再需要强制类型转换。
用枚举和数组设置变量
static const CGFloat systemAccessoryWidths[] = {
[UITableViewCellAccessoryNone] = 0,
[UITableViewCellAccessoryDisclosureIndicator] = 34,
[UITableViewCellAccessoryDetailDisclosureButton] = 68,
[UITableViewCellAccessoryCheckmark] = 40,
[UITableViewCellAccessoryDetailButton] = 48
};
contentViewWidth -= systemAccessoryWidths[cell.accessoryType];
给 Category 添加属性
_cmd 表示当前方法的selector
- (BOOL)fd_debugLogEnabled {
return [objc_getAssociatedObject(self, _cmd) boolValue];
}
可以注意下 Associated-objects 中有排小字:
Since SELs are guaranteed to be unique and constant, you can use _cmd as the key for objc_setAssociatedObject(). #objective-c #snowleopard
32 位和 64 位
#if CGFLOAT_IS_DOUBLE
return number.doubleValue;
#else
return number.floatValue;
#endif
NSNumber 中的浮点型变量取 double 还是 float 值,使用 CGFLOAT_IS_DOUBLE 判断,64 位的话则使用 double, 32 位的话则使用 float
参考文章
Runtime Programming Guide、
do while in macros
Objectice - C 特性