2011-12-18 64 views
34

我經常在iOS代碼中看到「聲明」,我將其谷歌,並知道它聲稱真假。如何知道NSAssert是否在發佈版本中被禁用?

我想知道這是否會在發佈模式下自動禁用?

+2

坦率地說,這是一個瘋狂的設計,默認情況下,在發佈版本中不會關閉斷言。在我知道的每個其他C編譯器面前飛行。 –

+0

@SevaAlekseyev同意,當發佈聲明仍然通過時,我們感到震驚。完全非常規。我們的理念是'快速發展,生產難'。 –

回答

38

使用NSAssert()及其同伴。

在項目中爲您的發佈配置定義NS_BLOCK_ASSERTIONS

Xcode 4 tremplates在發佈配置中禁用了NSAsserts。它增加了

-DNS_BLOCK_ASSERTIONS=1 

爲 「其他C標誌」 爲 「釋放」。

從文檔:如果宏NS_BLOCK_ASSERTIONS預處理器被定義

斷言被禁用。

NSAssert宏評估條件並作爲斷言處理程序的前端。

每個線程都有自己的斷言處理程序,它是類NSAssertionHandler的一個對象。調用時,斷言處理程序將輸出包含方法和類名稱(或函數名稱)的錯誤消息。然後它會引發一個NSInternalInconsistencyException異常。如果條件評估爲NO,宏將在當前線程的斷言處理程序上調用handleFailureInMethod:object:file:lineNumber:description:,並將desc作爲描述字符串傳遞。

該宏只能在Objective-C方法中使用。

4

當定義了NDEBUG時,斷言是有條件地編譯出代碼的。如果在相應的構建設置部分中定義了NDEBUG=1,則無論發行版或調試模式如何,都將停用代碼中的斷言。

24

我會在這裏提供一個元回答:

兩個@CocoaFu和@dasblinkenlight是正確的。 NS_BLOCK_ASSERTIONS關閉NSAssert()NDEBUG關閉assert()。如果您同時使用兩者,則需要兩者。

+0

通過@Rob閱讀iOS 5編程:獲取它,閱讀它,在iOS 5中更好地編程。 – zaph

+0

不幸的是,在您拼寫錯誤的兩個單詞的摘要中。 – Ant

+1

已註明並已修復。 NSDEBUG-> NDEBUG –

7

正如Zaph表示-DNS_BLOCK_ASSERTIONS=1已經發布。但是,如果你想檢查這一點。

首先在文檔中觀察到NSAssert已被宏NS_BLOCK_ASSERTIONS禁用。然後將其添加到構建和觀察它的規定確定:

#ifdef NS_BLOCK_ASSERTIONS 
#error Error - NS_BLOCK_ASSERTIONS is defined 
#endif 

然後改方案發布(CMD - 轉移 - <)

enter image description here

然後觀察了構建失敗。因此NS_BLOCK_ASSERTIONS定義爲NSAssert被禁用。

0

現在,從Xcode 6開始,設置爲ENABLE_NS_ASSERTIONS,默認情況下,其設置爲調試配置爲1,版本爲0

你可以選擇到它的發佈版本通過將ENABLE_NS_ASSERTIONS=1的說法,這是我正在做的運行單元測試檢查斷言條件在命令行上,但在其他方面應與DEBUG標誌關運行。

26

更新:驗證了這一點在Xcode 8中也適用。

在Xcode中7,進入項目構建設置,並在搜索欄中搜索「斷言」。這將顯示「Apple LLVM 7.0 - 預處理」部分。有一個名爲「啓用基礎聲明」的設置。

我已經成功地從那裏啓用/禁用NSAssert。

enter image description here

+2

,嚮應用的AppName.xcodeproj/project.pbxproj文件添加了一個ENABLE_NS_ASSERTIONS = NO;標誌 – computingfreak

0

這就是我在上面做我main()

#if defined(NDEBUG) 
{ 
    // The assertion code below should be compiled out of existence in a release 
    // build. Log an error and abort the program if it is not. 
    bool ok = true; 
    NSCAssert(ok = false, @"NS assertions should be disabled but are not"); 
    if (!ok) 
    { 
    NSLog(@"Detected release build but NS_BLOCK_ASSERTIONS is not defined"); 
    return -1; 
    } 
} 
#endif 

注意,因爲main()是一個C函數,而不是一個Objective-C的功能,NSCAssert上面使用,而不是NSAssert 。 (NSAssert預計self有效。)

相關問題