iOS代码重构的一些方法

最近项目已到尾声了。对于这个只是换汤不换药的新项目来说,开始接手的时候是有些抵触情绪的。经过熟悉了几个月,出于对职业的责任心,开始一直在公司的iOS讨论组里面分享知识,鼓励大家一起去改变这一切。希望能把共同认为是好的方式带进来。下面是最近进行代码重构的一些心得。

删掉死代码

诸如以下这些:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
        // Custom initialization
    }
    return self;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

使用Category


我们平时写UITableView是这样的:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellIdentifier = @"CellIdentifier";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    
    if(cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }
    //do something here
    return cell;
}
重构后:
.h文件
@interface UITableView (dequeue)
- (UITableViewCell *)dequeueCell;
@end
.m文件
@implementation UITableView (dequeue)

- (UITableViewCell *)dequeueCell
{
    static NSString *cellIdentifier = @"CellIdentifier";
    
    UITableViewCell *cell = [self dequeueReusableCellWithIdentifier:cellIdentifier];
    if(cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }
    return cell;
}
@end

//使用
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueCell];
    //do something here
    return cell;
}

使用NSDictionary映射字符串等

重构前:
    switch (expression) {
        case constant1:
            return @"result1";
        case constant2:
            return @"result2";
        ...
        case constantN:
            return @"resultN";
        default:
            return @"default";
    }
重构后:
    static NSDictionary *resultMap;
    if (!resultMap) {
        resultMap = @{@(constant1) : @"result1",
                      @(constant2) : @"result2",
                      ...
                      @(constantN) : @"resultN"};
    }
    
    return resultMap[expression] ?: @"default";
是不是逻辑上变得更清晰了呢?

Objective-C 动态方法

`NSSelectorFromString` 与 `[NSObject performSelector:]`

一般我们是这样写

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == 0) {
        [self func0];
    } else if (indexPath.row == 1) {
        [self func1];
    } else if (indexPath.row == N) {
        [self funcN];
    } else {
        [self doSomething];
    }
}
重构后

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    SEL funcSEL = NSSelectorFromString([NSString stringWithFormat:@"func%d", indexPath.row]);
    if ([self respondsToSelector:funcSEL]) {
        [self performSelector:funcSEL];
    } else {
        [self dosomething];
    }
}
加上 前一点 用NSDictionary 来映射字符串,是不是又多了一分想象力呢?

PS:基于以上两点,如果UITableView展示一些客户端固有的属性,可以将数据与点击的响应函数组织成一个字典,放在dataSource里面。

delegate 与 block

接口使用delegate好还是block好呢?个人选择如下:

对于那些block的生命周期里不会出现循环引用的优先选择block。否则选择delegate。

比如,`[NSArray enumerateObjectsUsingBlock:]`和UITableView的delegate两者。`[NSArray enumerateObjectsUsingBlock:]`中,即使有循环引用存在,也将在block在使用完毕后释放。而UITableView中,如果用block,出现循环引用需要自己打破。

基于以上选择规则,UIAlertView跟UISheetView中使用block也是可以的。重构之。

其它一些规则:

杜绝魔数。

使用NS_ENUM来枚举有规则的数。

尽量把变量的声明、定义放在最接近使用的地方。

使用最新的OC语法。

尽量精简方法。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值