NSLog(@"%@", boolVar) 會崩潰?BOOL 在 Objective-C 中本質是 有符號字符類型 (typedef signed char BOOL),取值 YES (1) / NO (0)。而 %@ 格式化符要求對應參數為 對象指針,並調用其 description 方法。將整數直接作為對象指針傳遞,會導致野指針解引用,直接 EXC_BAD_ACCESS 崩潰。
| 方案 | 代碼示例 | 輸出示例 | 適用場景 |
|---|---|---|---|
1. C 字符串格式 %s |
NSLog(@"BOOL: %s", b ? "YES" : "NO"); |
BOOL: YES |
最輕量,無對象創建開銷,適合高頻日志 |
2. NSString 對象格式 %@ |
NSLog(@"BOOL: %@", b ? @\"YES\" : @\"NO\"); |
BOOL: YES |
需對象參與拼接、本地化或進一步處理時 |
3. 整數格式 %d / %hhd |
NSLog(@"BOOL: %d", b); |
BOOL: 1 |
調試原始值、位運算、非標準 BOOL 值(如 2、-1)時 |
BOOL b = 2; // 非標準值,但 C 中非 0 即真
NSLog(@"%s", b ? "YES" : "NO"); // YES
NSLog(@"%@", b ? @\"YES\" : @\"NO\"); // YES
NSLog(@"%d", b); // 2 ← 關鍵:揭示真實存儲值
| 賦值 | %s/%@ (邏輯真假) |
%d (原始位模式) |
|---|---|---|
YES (1) |
YES | 1 |
NO (0) |
NO | 0 |
2 |
YES | 2 |
-1 |
YES | -1 |
%s / %@ 配合三元運算符反映 邏輯真值(非 0 即 YES)。%d 反映 存儲的原始位模式,可發現異常賦值(如 2、-1),調試時極有價值。%@ 直接打印 BOOL,這是導致崩潰的首要原因。
#define LOG_BOOL(name, val) NSLog(@"%s: %s (%d)", #name, (val) ? \"YES\" : \"NO\", (val))
// 使用:LOG_BOOL(isEnabled, flag); → "isEnabled: YES (1)"
%d 原始值,便於排查非標準 BOOL 賦值 Bug。Bool 嚴格為 true/false,橋接到 OC 會自動規範化為 1/0,但從 OC 讀取非規範值到 Swift 可能導致未定義行為。BOOL 本質是整數,%@ 需要對象,兩者不兼容導致崩潰。掌握 %s(輕量)、%@(對象化)、%d(原始值) 三種姿勢,並封裝為統一日志宏,即可徹底解決 BOOL 打印問題,同時提升調試效率。