吐个小槽

郑重声明:本文只是对编写代码过程中不合理的操作进行吐槽,同时希望能够将自己平时调试bug的思路进行分享,不附带对代码作者以及任何程序猿(媛)的人身攻击,请不要上纲上线。希望大家在阅读完这篇文章后能够以平常心对待从天而降的bug。(这其实是一篇技术博😏)

至于文中bug的始作俑(勇)者,我依然认为她是一个不可多得的合作伙伴。(谁还没写过几个惊天大bug)

开始之前,请大家打开网易云,搜索凉凉,带上耳机,扶好坐稳...

近期公司项目新增了一个大模块,然而在测试的时候偶然发现老早以前的模块某个xib文件约束报红,出于职业操守我计划顺便将这个模块进行测试,结果粗大事儿咧,模块中有一个界面的toolbar在我的疯狂点击下竟然纹丝不动。(手机钢化膜都戳破了,应该不是我力道不够的问题)

excuse me?这个toolbar有点冷,难道是我不够帅?不存在的,我让我们后台大帅比点了,也不行。😏(请不要留言要联系方式,人孩子都叫我叔叔了。)

稳重的toolbar

根据我多年的经验,如果这个toolbar一直是这样它不可能上线。(严肃脸)

想到这里我决定先给自己泡一杯菊花茶,可惜没有枸杞有点小遗憾。

作为一名合格的程序员,还是要勇于背锅的,也许是我某一天一不小心动了某行代码导致这里出问题了。
嗯,有道理,先回退版本build一下。
然而事实证明并没有什么卵用。那还等什么,甩锅啊!!!

望着手里的 iphoneXXX plus,我不经陷入了沉思.
它究竟经历了什么?
那是一个天气晴朗,万里无云,天空中飘着蒙蒙细雨的深夜,那一天我再次收到了系统版本升级通知,依稀记得那天没有枸杞,也没有菊花茶,有点微微发抖的手错误的按下了立即更新...
二十分钟后,望着系统焕然一新的手机,我又一次陷入了沉思... 唉,还是把Xcode也升级了吧。

哦!我知道了,一定是系统版本的原因,不是bug。找了旧版本的测试机build,看着活蹦乱跳的toolbar我的内心是崩溃的。

代码如下:

self.toobar = [[CSSMyCustomDetailToobar alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 44)];
[self.toobar toobarWithItems:itemArray[0]];

问题可能出在 CSSMyCustomDetailToobar :

@interface CSSMyCustomDetailToobar : UIToolbar
@property (nonatomic,assign) id <CSSMyCustomDetailToobarDelegate > delegateToobar;
- (void)toobarWithItems:(NSArray *)items;
@end

再看toobarWithItems方法:

- (void)toobarWithItems:(NSArray *)items 
{
    [items enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake((self.bounds.size.width/items.count)*idx, 0, self.bounds.size.width/items.count, self.bounds.size.height)];
        btn.tag = idx+10;
        if ([CSSUserInfoManager manager].isHiddenSwing) {
            btn.tag = btn.tag + 1;
        }
        [btn addTarget:self action:@selector(operationAction:) forControlEvents:UIControlEventTouchUpInside];
        UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:obj[@"image"]]];
        imageView.centerX  = btn.width/2;
        imageView.y = btn.frame.origin.y+5;

        UILabel *titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, [imageView getFrame_Bottom], btn.width, btn.height- [imageView getFrame_Bottom])];
        titleLabel.text = obj[@"title"];
        
        
        [btn addSubview:imageView];
        [btn addSubview:titleLabel];
        titleLabel.font = [UIFont systemFontOfSize:12];
        titleLabel.textColor = [UIColor see_colorWithHex:0x666666];
        titleLabel.textAlignment = NSTextAlignmentCenter;
      
        [self addSubview:btn]; //?????? why?
        
    }];
    self.backgroundColor = [UIColor whiteColor];
}

以上代码 除了 //?????? why? ,其他的都是原汁原味。

让我们来解析一下这段代码,借此琢磨一下作者当时的心路历程。

解析中
.
..
...
....
.....
......
.......
........
.........
..........
...........
............
解析失败!!!
是否强制解析,此操作可能会造成无法挽回的后果。 (y / n)
y
😒

从上面的代码来看,这里应该是想要把button添加在toolbar上面,这个是没毛病的。
but...
wait, wait, wait,等一下...
[self addSubview:btn]; ???
视图层次结构走起来。

iOS11.4系统下toolbar层次结构

怪不得点不动,按钮上面盖四层视图是什么鬼?
切回旧版本系统看一下

iOS10.0系统下toolbar层次结构

纵观不同系统下层次结构,不难发现两个系统版本下调用UIToolbar的addSubview:方法视图添加的位置是不同的。
iOS10.0下按钮被添加在_UIVisualEffectFilterView上层,处于所有子视图之上,zIndex最大。
iOS11下UIToolbar多了_UIToolbarContentView和_UIButtonBarStackView两层视图并且这两层视图是在_UIVisualEffectSubview之上的,而我们的按钮就被添加在_UIVisualEffectSubview上层,因此我们添加的按钮就被_UIToolbarContentView和_UIButtonBarStackView覆盖了接收不到点击事件。

嗯,终于找到了原因看来能够早点下班回家了。
重新修改代码,使用按钮创建UIBarButtonItem并添加进toolbar,千万别问我UIBarButtonItem怎么添加到toolbar。

迫不及待的build一下,fuck,竟然还是不能点。
感觉我的智商受到了惨无人道的侮辱。
再看看视图层次结构:

iOS11.4下视图层次结构

竟然少了两层,不错不错,还是取得了一点点成就的。
我们发现,修改之前按钮上面 _UIToolbarContentView和_UIButtonBarStackView 各有两层,现在只剩一层了,少的那一层去哪里了呢?
我们在图中找找线索:

iOS11.4下视图层次结构

由此猜测,可能这一坨视图是由两个toolbar合成的。(为我自己的机智点个赞👍)
其中一个toolbar被另一个toolbar使用addSubview方法添加进自己的视图。
通过不懈的努力,在控制器中发现了以下代码:

[self.navigationController.toolbar addSubview:self.toobar];
self.navigationController.toolbarHidden = NO;

@¥#%@……#%……@#&*¥#……
咳咳... 不好意思,语速太快岔气了。
进过一番苦战,toolbar终于正常工作,你以为就能下班了?
too young too naive!

不知各位之前有没有注意到下面这几行代码:

 UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake((self.bounds.size.width/items.count)*idx, 0, self.bounds.size.width/items.count, self.bounds.size.height)];
 UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:obj[@"image"]]];
 imageView.centerX  = btn.width/2;
 imageView.y = btn.frame.origin.y+5;
 UILabel *titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, [imageView getFrame_Bottom], btn.width, btn.height- [imageView getFrame_Bottom])];
 titleLabel.text = obj[@"title"];
 [btn addSubview:imageView];
 [btn addSubview:titleLabel];
 titleLabel.font = [UIFont systemFontOfSize:12];
 titleLabel.textColor = [UIColor see_colorWithHex:0x666666];
 titleLabel.textAlignment = NSTextAlignmentCenter;

说到这几行代码那可就牛逼了,又是加减又是乘除的,一看就是出自文化人之手。

虽然这几行代码运行出来的结果是没问题的,但是怎么就看着这么奇怪呢,这里是通过给button添加了一个UIImageView和一个UILabel然后进行了一系列运算计算frame来实现文字和图片的折行显示(图文混排),但是这种方法看起来好像有那么一点点不优雅。

其实这里可以采用属性字符串来达到同样的效果,代码如下:

+ (instancetype)see_attributedStringWithImage:(UIImage *)image imageSize:(CGSize)size title:(NSString *)title titleColor:(UIColor *)color fontSize:(CGFloat)fontSize lineSpace:(CGFloat)space {
    //创建文本附件
    NSTextAttachment * atta = [[NSTextAttachment alloc]init];
    //设置图片
    atta.image = image;
    //设置图片大小
    atta.bounds = CGRectMake(0, 0, size.width, size.height);
    NSAttributedString * att = [NSAttributedString attributedStringWithAttachment:atta];
    //追加空行
    NSMutableAttributedString * attM = [[NSMutableAttributedString alloc]initWithAttributedString:att];
    NSAttributedString * str = [[NSAttributedString alloc]initWithString:@"\n " attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:space]}];
    [attM appendAttributedString:str];
    //追加文字
    NSAttributedString * titles = [[NSAttributedString alloc]initWithString:[NSString stringWithFormat:@"\n%@",title] attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize],NSForegroundColorAttributeName:color}];
    [attM appendAttributedString:titles];
    return attM.copy;
}

这样可以省去很多不必要的数学运算。

至此本期吐槽结束。

至于这段代码出自何人之手并不重要,(谁还没有年轻过,毕竟大家都是从菜鸡一步步过来的。)重要的是目前线上App在iOS11.4版本的设备上是瘫痪的... 我的内心受到了极大的伤害(疼痛到无法夫吸),不说了改胤禩(八阿哥)去。

(以下情节纯属虚构,如有雷同纯属巧合,请随意入座。)
一年前:
NSLog(@"h");
NSLog(@"e");
NSLog(@"l");
NSLog(@"l");
NSLog(@"o");
NSLog(@" ");
NSLog(@"w");
NSLog(@"o");
NSLog(@"r");
NSLog(@"l");
NSLog(@"d");

唉呀妈呀,终于写完了。

嗯,不错,我这段代码老牛逼了。后面来的人看到了我这段代码一定会对我顶礼膜拜。
要不然署个名留个联系方式?
算了算了,做人要低调,低调,低调!

一年后:

嗯? 这里好像有一个bug。

嗯... 这个bug值得好好研究一下。

咦?这里为什么要这样写呢?

妈的,这sb代码谁写的。@#¥¥&¥#(@#()@😒

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,997评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,603评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,359评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,309评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,346评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,258评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,122评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,970评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,403评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,596评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,769评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,464评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,075评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,705评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,848评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,831评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,678评论 2 354

推荐阅读更多精彩内容

  • 最近在回顾经典,连着两个月都在看武侠小说。在中学时期,我特别喜欢看古龙。而现在古龙金庸连着看,发现对金庸小说的喜欢...
    修炼的大海阅读 237评论 0 1
  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明先生_X自主阅读 15,979评论 3 119
  • 最近深深被一种我配不上的思想困扰。静下来梳理出来,想给自己一点鼓励。 “我不配”的思想,其实是一种潜意识,扎根在我...
    卡诺09阅读 535评论 0 0
  • 1988年的电视剧《八月桂花香》的主题曲,那个时候电视剧好少啊,对这部电视剧记忆尤深,主题曲也是特别好听。 尘缘 ...
    JessicaH2017阅读 588评论 6 10
  • 曾一直以为写作必须行云流水,潇洒飘逸,一气呵成,斗酒诗百篇,才发现,那不过是神话故事和谣言。 多数人写作往往都会遇...
    六婶儿阅读 119评论 2 1