簡體   English   中英

如何禁用日志記錄?

[英]How to disable logging?

我有一個使用Apple提供的UITextChecker類的應用程序。 此類有以下錯誤:如果iOS設備每次我調用UITextChecker的某些方法都脫機時(預期對於我的應用程序來說經常如此),它將記錄到控制台:

2016-03-08 23:48:02.119 HereIsMyAppName [4524:469877] UITextChecker sent string:isExemptFromTextCheckerWithCompletionHandler: to com.apple.TextInput.rdt but received error Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.apple.TextInput.rdt was invalidated."

我不希望此郵件發送垃圾郵件。 有沒有辦法禁用代碼日志記錄? 我將在調用UITextChecker的任何方法之前禁用日志記錄,然后再啟用它。 還是有什么辦法可以有選擇地禁用每個類的日志記錄(如果是基礎類而不是我的,則會發生事件)? 或其他解決方案?

警告 :此答案使用了尚未公開的可可C函數_NSSetLogCStringFunction()_NSLogCStringFunction()

_NSSetLogCStringFunction()是Apple創建的用於處理NSLog的實現功能的接口。 WebObjects最初暴露給Windows機器上的NSLog語句,但如今仍存在於iOS和OS X API中。 支持文章中對此進行了記錄。

該函數接收帶有參數const char* message ,要記錄的字符串, unsigned length ,消息的長度以及帶有BOOL withSysLogBannerBOOL withSysLogBanner的函數指針,該BOOL withSysLogBanner切換標准日志記錄BOOL withSysLogBanner的信息。 如果我們創建自己的鈎子函數來進行日志記錄,而實際上它並沒有做任何事情(一個空的實現,而不是像NSLog那樣在幕后調用fprintf ),那么我們可以有效地禁用應用程序的所有日志記錄。

Objective-C示例(或帶有橋接頭的Swift):

extern void _NSSetLogCStringFunction(void(*)(const char*, unsigned, BOOL));

static void hookFunc(const char* message, unsigned length, BOOL withSysLogBanner) { /* Empty */ }

// Later in your application

_NSSetLogCStringFunction(hookFunc);

NSLog(@"Hello _NSSetLogCStringFunction!\n\n");  // observe this isn't logged

可以在YILogHook中找到此示例的實現,它提供了一個接口,用於將塊數組添加到任何NSLog語句(寫入文件等)。

純Swift示例:

@asmname("_NSSetLogCStringFunction") // NOTE: As of Swift 2.2 @asmname has been renamed to @_silgen_name
func _NSSetLogCStringFunction(_: ((UnsafePointer<Int8>, UInt32, Bool) -> Void)) -> Void

func hookFunc(message: UnsafePointer<Int8>, _ length: UInt32, _ withSysLogBanner: Bool) -> Void { /* Empty */ }

_NSSetLogCStringFunction(hookFunc)

NSLog("Hello _NSSetLogCStringFunction!\n\n");  // observe this isn't logged

在Swift中,您還可以選擇忽略所有塊參數,而無需使用hookFunc如下所示:

_NSSetLogCStringFunction { _,_,_ in }

要使用Objective-C重新登錄,只需傳入NULL作為函數指針:

_NSSetLogCStringFunction(NULL);

與Swift有所不同,因為如果我們嘗試傳遞nilnil指針,編譯器將抱怨類型不匹配(在Swift中NULL不可用)。 為了解決這個問題,我們需要訪問另一個系統函數_NSLogCStringFunction ,以獲取指向默認日志記錄實現的指針,在禁用日志記錄時保留該引用,並在希望重新打開日志記錄時將其設置回。

我通過添加NSLogCStringFunc typedef清理了Swift的實現:

/// Represents the C function signature used under-the-hood by NSLog
typealias NSLogCStringFunc = (UnsafePointer<Int8>, UInt32, Bool) -> Void

/// Sets the C function used by NSLog
@_silgen_name("_NSSetLogCStringFunction") // NOTE: As of Swift 2.2 @asmname has been renamed to @_silgen_name
func _NSSetLogCStringFunction(_: NSLogCStringFunc) -> Void

/// Retrieves the current C function used by NSLog
@_silgen_name("_NSLogCStringFunction")
func _NSLogCStringFunction() -> NSLogCStringFunc

let logFunc = _NSLogCStringFunction() // get function pointer to the system log function before we override it

_NSSetLogCStringFunction { (_, _, _) in } // set our own log function to do nothing in an anonymous closure

NSLog("Observe this isn't logged.");

_NSSetLogCStringFunction(logFunc) // switch back to the system log function

NSLog("Observe this is logged.")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM