[iOS] 簡單總結下新項目消滅的300多個warning

1. 背景

因為種種原因,當了回接盤俠.
拿到一個運動類APP, 一打開,我去,編譯了好半天,文件大的不得了. 然后就看見那個warning蹭蹭蹭的往上漲.
等編譯完定睛一看,我擦371個warning.

app_warning.png

雖然這只是warning,不影響APP的正常運行.
但是
且不說,影響編譯效率,耗費時間,而且有潛在bug風險,光本著強迫癥習慣這一個理由,就足以決定先停下其他事情,把warning清一清.
否則,根本無心工作啊...

2. 開始清

剛好是端午節, 除了第一天陪妹子去無錫玩了一天,剩下兩天就耗在這個上面了.
不過意外在徐匯發現一個不錯的圖書館:Instituto Cervantes(塞萬提斯圖書館)(就是寫堂吉訶德的那個作者),整個清理過程大部分就是在這里完成的:

2.pic.jpg

清理完,長呼一口氣...

okey,下面是清理完的截圖:

屏幕快照 2016-06-12 下午8.57.09.png

polen: 最后一個warning是CocoaLumberjack的自定義一個紅開關warning,嚴格說就不算warning了,暫且忽略之...

<br >

3. 回顧下都有哪些warning

雖然數量很多,但是種類來說,其實就那么幾條. 因為里面大部分warning都是C/C++代碼的warning,其實對iOS開發的指導意義并不大,這里挑選其中比較有用或者有意義的整理下:

3.1 方法棄用類

3.1.1 sizeWithFont

sizeWithFont

iOS 7.0以前獲取字體所占空間大小的方法,很好用.不過現在棄用了,這個很好改(用新方法:boundingRectWithSize):

官方說明

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(NSLineBreakMode)lineBreakMode 
NS_DEPRECATED_IOS(2_0, 7_0, "Use -boundingRectWithSize:options:attributes:context:") __TVOS_PROHIBITED; 
// NSTextAlignment is not needed to determine size

FIX:

寫了個NSString的Category,里面實現了boundingRectWithSize,所有用到的地方直接調用這個就可以了.

- (CGSize)sizeOfFont:(UIFont*)font andWidth:(float)width {
  NSDictionary* attribute = @{NSFontAttributeName : font};

  CGSize retSize =
      [self boundingRectWithSize:CGSizeMake(width, 9999999)
                         options:NSStringDrawingTruncatesLastVisibleLine |
                                 NSStringDrawingUsesLineFragmentOrigin |
                                 NSStringDrawingUsesFontLeading
                      attributes:attribute
                         context:nil]
          .size;

  return retSize;
}

<br >

3.1.2 NSDateComponents.week

week

做過日歷的童鞋肯定懂,關于NSDateComponents的week,新增了weekOfMonth or weekOfYear,以前直接調用week的方法棄用了.

官方說明

- (NSInteger)week 
NS_CALENDAR_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use weekOfMonth or weekOfYear, depending on which you mean");
- (void)setWeek:(NSInteger)v 
NS_CALENDAR_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use setWeekOfMonth: or setWeekOfYear:, depending on which you mean");

這個改起來稍微麻煩一點,也還好,這個是在顯示時間的地方(顯示類似"3周前")代碼里使用了
NSDate+Helper這個開源庫,但是源碼Github上找不到了,
隨徒手改之:

FIX:

- (NSInteger)weeksFrom:(NSDate*)date calendar:(NSCalendar*)calendar {
  if (!calendar) {
    calendar = [[self class] implicitCalendar];
  }

  NSDate* earliest = [self earlierDate:date];
  NSDate* latest = (earliest == self) ? date : self;
  NSInteger multiplier = (earliest == self) ? -1 : 1;
  NSDateComponents* components = [calendar components:NSCalendarUnitWeekOfYear
                                             fromDate:earliest
                                               toDate:latest
                                              options:0];
  return multiplier * components.weekOfYear;
}

<br >

3.2 Directory not found for option ...

not found

這個是編譯時找不到對應的framework,可能這個framework你已經不用了,但是Search Paths 沒有清除掉.在build setting->Framework Search Paths 刪除掉你Not found的目錄即可.

屏幕快照 2016-06-12 下午5.03.59.png

參照:
消除 Xcode7 中 directory not found for option 'xxxx' 警告
Apple Developer: warning: directory not found

<br >

3.3 The app icon set "AppIcon" has an unassigned child

The app icon set

這個是images.scassets 出了問題,找到你的AppIcon,刪除掉Unassigned的圖片即可,(如果是空的也要刪除)

AppIcon Unassigned

參照:
http://stackoverflow.com/questions/29433670/app-icon-has-unassigned-image-error

<br >

3.4 'kCFStreamSSLAllowsExpiredCertificates' is deprecated: fitst deprecated in iOS 4.0

kCFStreamSSLAllowsExpiredCertificates

官方說明

kCFStreamSSLAllowsExpiredCertificates:
kCFStreamSSLAllowsExpiredRoots:
kCFStreamSSLAllowsAnyRoot:

The SSL handshake flags which affect untrusted certificate chain evaluation are deprecated. Instead, use the single property kCFStreamSSLValidatesCertificateChain to disable certificate chain checking if the user has decided that it is appropriate to do so
So the simple solution is to remove the deprecated keys and their values. Keep only kCFStreamSSLValidatesCertificateChain and kCFStreamSSLPeerName in the sslProperties dictionary.

這個代碼沒有用AFNetwork,用的是ASIHttpRequest(看來也是代碼比較長久了...)
kCFStreamSSLAllowsExpiredCertificates已經棄用了.

FIX:

方案A: 移除掉就可以了.

NSDictionary* sslProperties = [[NSDictionary alloc]
      initWithObjectsAndKeys:[NSNumber numberWithBool:NO],
                             kCFStreamSSLValidatesCertificateChain, kCFNull,
                             kCFStreamSSLPeerName, nil];

方案B: 加一條
#pragma clang diagnostic ignored "-Wdeprecated-declarations".

參照:

<br >

3.4 'delete' applied to a pointer that was allocated with 'new[]';did you mean 'delete[]'?

delete[]

這是c++的代碼,delete刪除的時候,如果對象是new[]出來的,對應刪除需要采用delete[].這個估計是當時寫代碼的家伙手抖了,筆誤...

polem:
記住規則:malloc/free, new/delete, new[]/delete[])

官方說明

In the first alternative (delete object), the value of the operand of delete shall be a pointer to a non-array object or a pointer to a sub-object (1.8) representing a base class of such an object (clause 10). If not, the behavior is undefined.
In the second alternative (delete array), the value of the operand of delete shall be the pointer value which resulted from a previous array new-expression. If not, the behavior is undefined.

delete :
calls the appropriate destructor only for the element pointed to (if needed), then frees the memory chunk
delete[] :
calls the appropriate destructors for each element in its array (if needed), then frees the memory chunk

參照:
http://stackoverflow.com/questions/4255598/delete-vs-delete

FIX:

delete[] session_info_buf;

<br >

3.5 'Register' storage class specifier is deprecated

Register' storage class specifier

register作為關鍵字修飾的變量,意思其修飾的變量可能會被頻繁調用,所以期望保存在CPU的寄存器中(一般都是存在堆或者棧之中),這樣可以加快處理速度.(補充:標識符的類型知識可以看這里

但是如今的編譯器并不會太理會這些東西,所以有點"然并卵"的即視感. 后來,C++17中直接給棄用掉了.

屏幕快照 2016-06-12 下午6.20.50.png

鏈接:
http://en.cppreference.com/w/cpp/language/storage_duration

FIX:

方案A:直接刪掉register就好了

int myrandom32() {
  if (_rg.Null()) {
    int a;
    int b;
    tUInt32 c;
...

方案B:
忽略掉這個警告,-Wdeprecated-register

#pragma clang diagnostic ignored "-Wdeprecated-register"

參照這里:http://stackoverflow.com/questions/22422741...

<br >

3.6 Automatic Preferred Max Layout Width before iOS 8.0

Automatic Preferred Max Layout Width

瞧瞧,瞧瞧,多少這種warning,這種就是,在做layout 的時候,設置了labe的numberoflines 是0, 但是沒設置Preferred Width導致的.當然這里面有個比較麻煩的時候,如果xib有多個label,逐個去找哪個沒設置,是比較耗費時間和精力的,但是xcode的warning又沒有詳細的告訴你是哪個label出問題了(很不人性化),所以需要看Source Code里的id對應到label 的Object Id,具體看這里:
To Find the problem label(s) in a large storyboard...

Fix:

屏幕快照 2016-06-12 下午6.06.16.png

<br >

3.7 ignore waning

其他很多warning是c代碼里面的,unused或者類型不對的,什么long和int或者unsigned int等等,這些沒啥技術含量,逐個修改就好了.

最后還有一個萬能方法是:如果你已經百分百確定這個文件的warning不用修復,百分百確定是安全的,那么你可以忽略這個警告.

(如果有些同學是從MRC 過度到ARC的,那就知道這里(設置-fno-objc-arc的地方))
加一個-w即可

Target->Build Phases->Compile Sources->對應的文件

-w

<br >


by polen

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容