前言
本文分享iOS開發(fā)中遇到的問題汁蝶,和相關(guān)的一些思考渐扮。
正文
一、Xcode10.1 import頭文件無法索引
【問題表現(xiàn)】如圖掖棉,當(dāng)import頭文件的時(shí)候墓律,索引無效,無法聯(lián)想出正確的文件幔亥;
【問題分析】通過多個(gè)文件嘗試耻讽,發(fā)現(xiàn)并非完全不能索引頭文件,而是只能索引和當(dāng)前文件在同級(jí)目錄的頭文件帕棉;
有點(diǎn)猜測是Xcode10.1的原因针肥,但是在升級(jí)完的半年多時(shí)間里饼记,都沒有出現(xiàn)過索引。
從已有的知識(shí)來分析慰枕,很可能是Xcode的頭文件搜索路徑有問題具则,于是嘗試把工程文件下的路徑設(shè)置遞歸搜索,結(jié)果又出現(xiàn)以下問題:
【問題解決】在多次嘗試無效之后具帮,最終還是靠Google解決該問題博肋。
如下路徑,修改設(shè)置
Xcode --> File --> Workspace Settings --> Build System --> Legacy Build System
二匕坯、NSAssert的斷點(diǎn)和symbolic 斷點(diǎn)
【問題表現(xiàn)】NSAssert是常見的斷言束昵,可以在debug階段快速暴露問題拔稳,但是在觸發(fā)的時(shí)候無法保持上下文葛峻;
【問題分析】NSAssert的本質(zhì)就是拋出一個(gè)異常,可以通過Xcode添加一個(gè)Exception Breakpoint:
如下巴比,便可以NSAssert觸發(fā)時(shí)捕獲現(xiàn)場术奖。
同理,在Exception Breakpoint轻绞,還有Smybolic Breakpoint較為常用采记。
以cookie設(shè)置接口為例,以下為一段設(shè)置cookies的代碼
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies];
但是有時(shí)候設(shè)置cookies的地方可能較多政勃,此時(shí)可以添加一個(gè)Smybolic Breakpoint并設(shè)置符號(hào)為cookies唧龄。
如下,可以看到所有設(shè)置cookies的接口:
三奸远、.m文件改成.mm文件后編譯失敗
【問題表現(xiàn)】Pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)
出錯(cuò)代碼行: typedef void(^SSDataCallback)(NSError *error, id obj);
手動(dòng)給參數(shù)添加 nullable的聲明并無法解決既棺。
【問題分析】
首先確定的是,這個(gè)編譯失敗實(shí)際上是一個(gè)warning懒叛,只是因?yàn)楣こ淘O(shè)置了把warning識(shí)別為error丸冕;
其次.m文件可以正常編譯,并且.m文件也是開啟了warning as error的設(shè)置薛窥;而從改成.mm就報(bào)錯(cuò)的表現(xiàn)和提示log來看胖烛,仍然是因?yàn)閰?shù)為空的原因?qū)е隆?/p>
【問題解決】
經(jīng)過對比正常編譯的.mm文件,找到一個(gè)解決方案:
1诅迷,添加NS_ASSUME_NONNULL_BEGIN
在代碼最前面佩番,NS_ASSUME_NONNULL_END
在代碼最后面;
2罢杉、手動(dòng)添加_Nullable到函數(shù)的參數(shù)趟畏;
typedef void(^SSDataCallback)(NSError * _Nullable error, id _Nullable obj);
四、UITabbar疑難雜癥
問題1屑那、batItem的染色異常問題
【問題表現(xiàn)】添加UITabBarItem到tabbar上拱镐,但是圖片會(huì)被染成藍(lán)色艘款;
【問題分析】tabbar默認(rèn)會(huì)幫我們?nèi)旧晕覀儎?chuàng)建的UITabBarItem默認(rèn)會(huì)被tinkColor染色的影響沃琅。
解決辦法就是添加參數(shù)imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal
哗咆,這樣UITabBarItem的圖片變不會(huì)受到tinkColor影響。
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"商城" image:[UIImage imageNamed:@"tabbar_item_store"] selectedImage:[[UIImage imageNamed:@"tabbar_item_store_selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];
問題2益眉、tabbar的背景色問題
【問題表現(xiàn)】設(shè)置tabbar的背景色是0xFFFFFF的白色晌柬,但是實(shí)際的效果確是灰白色,并不是全白色郭脂;
【問題分析】tabbar默認(rèn)是透明的(屬性translucent)年碘,會(huì)對tabbar下面的視圖進(jìn)行高斯模糊,然后再與背景色混合展鸡。
【問題解決】
1屿衅、自由做法,addSubview:一個(gè)view到tabbar上莹弊,接下來自己繪制4個(gè)按鈕涤久;(可操作性強(qiáng),缺點(diǎn)是tabbar的邏輯需要自己再實(shí)現(xiàn)一遍)
2忍弛、改變tabbar透明度做法响迂,設(shè)置translucent=YES,再修改背景色细疚;(引入一個(gè)巨大的坑蔗彤,導(dǎo)致UITabbarViewController上面的子VC的self.view屬性高度會(huì)變化!)
3疯兼、空白圖做法然遏,把背景圖都用一張空白的圖片替代,如下:(最終采納的做法)
self.tabBar.backgroundImage = [[UIImage alloc] init];
self.tabBar.backgroundColor = [UIColor whiteColor];
問題3镇防、tabbar頂部的線條問題
【問題表現(xiàn)】UITabbar默認(rèn)在tabbar的頂部會(huì)有一條灰色的線啦鸣,但是并沒有一個(gè)屬性可以修改其顏色。
【問題分析】從Xcode的工具來看来氧,這條線是一個(gè)UIImageView:
再從UITabbar的頭文件來看诫给,這條線的圖片可能是shadowImage。
【問題解決】將shadowImage用一張空白的圖片替代啦扬,然后自己再添加想要的線條大小和顏色中狂。
self.tabBar.shadowImage = [[UIImage alloc] init];
UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tabBar.width, 0.5)];
lineView.backgroundColor = [UIColor colorWithHexString:@"e8e8e8"];
[self.tabBar addSubview:lineView];
五、特殊機(jī)型出現(xiàn)的異称苏保現(xiàn)象
1胃榕、iOS 11.4 充電時(shí)無法正常獲取電量
【問題表現(xiàn)】在某個(gè)場景需要獲取電池,于是通過以下addObserverForName:UIDeviceBatteryLevelDidChangeNotification
的方式監(jiān)聽電量的變化瞄摊,在iOS 12的機(jī)型表現(xiàn)正常勋又,但是在iOS 11.4的機(jī)型上會(huì)出現(xiàn)無法獲取電量的原因苦掘。
void (^block)(NSNotification *notification) = ^(NSNotification *notification) {
SS_STRONG_SELF(self);
NSLog(@"%@", self);
self.batteryView.width = (self.batteryImageView.width - Padding_battery_width) * [UIDevice currentDevice].batteryLevel;
};
//監(jiān)視電池剩余電量
[[NSNotificationCenter defaultCenter] addObserverForName:UIDeviceBatteryLevelDidChangeNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:block];
【問題分析】從電量獲取的api開始入手分析,在獲取電量之前楔壤,需要顯式調(diào)用接口
[UIDevice currentDevice].batteryMonitoringEnabled = YES;
于是點(diǎn)擊batteryMonitoringEnabled屬性進(jìn)入U(xiǎn)IDevice.h鹤啡,發(fā)現(xiàn)有個(gè)batteryState屬性,里面有一個(gè)狀態(tài)是充電UIDeviceBatteryStateCharging蹲嚣,但是對問題并無幫助递瑰;
點(diǎn)擊UIDeviceBatteryLevelDidChangeNotification
發(fā)現(xiàn)還有一個(gè)通知是UIDeviceBatteryStateDidChangeNotification
,猜測可能是充電狀態(tài)下的回調(diào)有所不同隙畜;
【問題解決】最終通過添加新通知的監(jiān)聽解決抖部。該問題并不太難,但是養(yǎng)成多看.h文件相關(guān)屬性的習(xí)慣议惰,還是會(huì)有好處慎颗。
[[NSNotificationCenter defaultCenter] addObserverForName:UIDeviceBatteryStateDidChangeNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:block];
2、iOS 10.3的UILabel富文本排版異常
【問題表現(xiàn)】有一段文本的顯示需要設(shè)置首行縮進(jìn)换淆,所以用的富文本添加段落屬性的方式哗总;但是在iOS 10.3的6p機(jī)型上出現(xiàn)異臣秆眨現(xiàn)象倍试,如下:
測試文本:contentStr=@"一年佛山電腦放山東難道是防空洞念佛"
如下,最后的字符沒有顯示完全蛋哭。
實(shí)現(xiàn)方式是計(jì)算得到富文本县习,然后賦值給UILabel,再調(diào)用-sizeToFit的接口谆趾。
以上的問題僅在一行的時(shí)候出現(xiàn)異常躁愿,兩行又恢復(fù)正常。
【問題分析】
從表現(xiàn)來看沪蓬,是sizeToFit的時(shí)候?qū)挾冉Y(jié)算出錯(cuò)彤钟;通過多次嘗試,發(fā)現(xiàn)是少計(jì)算了大概兩個(gè)空格的距離跷叉,也即是首行縮進(jìn)的距離逸雹。
【問題解決】
方法1、去除首行縮進(jìn)云挟,每行增加兩個(gè)空格梆砸;
方法2、一行的時(shí)候园欣,把寬度設(shè)置到最大帖世;
如何判斷1行的情況,可以用以下的代碼簡短判斷
if (self.contentLabel.height < self.contentLabel.font.lineHeight * 2) { // 一行的情況
self.contentLabel.width = self.width - 40;
}
總結(jié)
日常開發(fā)遇到的問題沸枯,如果解決過程超過10分鐘日矫,我都會(huì)記錄下來赂弓。
這些問題有的很簡單,僅僅是改個(gè)配置(如第一個(gè)Xcode索引問題)哪轿,但是在解決過程中還是走了一些彎路拣展,因?yàn)橥耆珱]想過可能會(huì)去改Workspace setting,都是在Build setting修改進(jìn)行嘗試缔逛。
還有些問題純粹是特定現(xiàn)象备埃,比如說特殊機(jī)型問題,只是做一個(gè)備忘和提醒褐奴。