记一次帮同事排查由命名引发的问题

今天同事在群里发了一个问题,问有没有人碰到类似如下的问题:

-[UILabel stringByTrimmingCharactersInSet:]: unrecognized selector sent to instance 0x7ff08c865970

一位同事第一反应是不是对象被释放了,出现了野指针?

然而加上异常断点、开启Zombie诊断后,并没有带来有用的信息。


我转身问是不是必现的?回答是的。

于是我建议直接给UILabel加个stringByTrimmingCharactersInSet:方法,然后打个断点,就可以从调用栈看出是哪里在调用——结果,整个主线程都是系统框架在调用。

但是从主线程调用栈还是可以看到跟UITableView的代理回调方法有关——具体是跟sectionHeader的获取有关。

我们通过直接注释掉相关方法得到了验证:

- (nullable UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section

的确是跟这里有关,注释掉后问题消失。

那问题基本就落在headerView的布局上了,这是一个继承自UITableViewHeaderFooterView的子类,点击.h头文件一看,我瞄到了有个UILabel *类型变量叫做text。这样的命名会让我心里一纠结,所以很快就感知到了,因为我会命名为textLabel。

于是我说,这样的命名很容易出现问题,容易发生“将这样命名的变量当做NSString *类型进行传递”的现象。

通过修改属性名称,并且在进行一处处替换的过程中我认真地看着有没有将其错误使用,然而并没有——但是问题还是得到解决了。

于是我们推测,在基类中有NSString *类型的变量名为text,但是在子类中重写了它,导致类型变化,进而引发了问题。


这又让我想起:

There are only two hard things in Computer Science: cache invalidation and naming things.

-- Phil Karlton


猜你喜欢

转载自blog.csdn.net/jasonblog/article/details/51203961