最近開發(fā)中為了方便自己測試责循,準(zhǔn)備弄個簡單業(yè)務(wù)錯誤日志統(tǒng)計。由于只是測試用,況且出現(xiàn)我認(rèn)為可能錯的情況幾率很小。想在不改變現(xiàn)有代碼的情況下殷绍,直接獲取NSLog內(nèi)容。查了些資料鹊漠,知道NSLog輸出的內(nèi)容會寫到控制臺和系統(tǒng)日志(ASL)里面主到。我就想在輸入到ASL的時候把特定的數(shù)據(jù)給保存下來。但是我無法知道NSLog什么時候輸出內(nèi)容躯概,看到網(wǎng)上開源的DDLogger的源碼登钥,找到了解決的方法。原來只是需要注冊下系統(tǒng)的通知就可以拿到輸出的時機(jī)娶靡,然后通過<asl.h>提供的方法去操作系統(tǒng)設(shè)備log牧牢。
notify.h
這個頭文件里面提供了用于進(jìn)程之間的無狀態(tài)通知方法。用法和我們通知使用差不多姿锭。
//通知的注冊
int token;
notify_register_dispatch("com.apple.system.logger.message", &token, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(int token) {
NSLog(@"receive nofity");
});
//發(fā)送通知塔鳍。
notify_post("com.apple.system.logger.message");
//通知取消
notify_cancel(token);
從用法上,可以看出發(fā)通知只能用通知的名字呻此,而且不能傳遞參數(shù)轮纫。由于這個是通過操作系統(tǒng)發(fā)出的,換句話說焚鲜,只要不同的進(jìn)程注冊了同一個通知名掌唾,當(dāng)發(fā)送notify_post的時候,所有的進(jìn)程都會收到忿磅。自己做了個測試糯彬,開啟兩個app,隨便弄個自己的通知葱她,然后其中一個app進(jìn)行注冊情连,另一個app進(jìn)行發(fā)送,的確能收到通知览效。
我們也可以通過CFNotificationCenter提供的方法去注冊這些通知却舀,它的實現(xiàn)也是基于<notify.h>里面的API。
狀態(tài)的設(shè)置
當(dāng)我們第一次注冊某個通知時候锤灿,可能并不知道當(dāng)前資源是否可以使用挽拔,必須等待下一次的通知回調(diào)。系統(tǒng)也提供了一個解決方法但校,如果是發(fā)送方螃诅,在資源可以使用的時候做一個標(biāo)記位,接受方状囱,在注冊之前可以先檢查下术裸,當(dāng)前資源是否可以使用,如果可以使用亭枷,可以直接進(jìn)入自己的邏輯處理袭艺。
//發(fā)送方
int token;
notify_register_check("customMessage", &token);
uint64_t state = 1;
notify_set_state(token, state);
//接受方
int token;
notify_register_check("customMessage", &token);
uint64_t state;
notify_get_state(token, &state);
if (state) {
//logic
}
//注冊通知
notify_register_dispatch("com.apple.system.logger.message", &token, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(int token) {
NSLog(@"receive nofity");
});
notify_keys.h
系統(tǒng)提供了一些我們可以注冊的通知:
/*
* Directory Service notifications
* These are posted by the DirectoryService daemon to advise clients that
* cached data should be invalidated.
*/
#define kNotifyDSCacheInvalidation "com.apple.system.DirectoryService.InvalidateCache"
#define kNotifyDSCacheInvalidationGroup "com.apple.system.DirectoryService.InvalidateCache.group"
#define kNotifyDSCacheInvalidationHost "com.apple.system.DirectoryService.InvalidateCache.host"
#define kNotifyDSCacheInvalidationService "com.apple.system.DirectoryService.InvalidateCache.service"
#define kNotifyDSCacheInvalidationUser "com.apple.system.DirectoryService.InvalidateCache.user"
/*
* File System notifications
* These advise clients of various filesystem events.
*/
#define kNotifyVFSMount "com.apple.system.kernel.mount"
#define kNotifyVFSUnmount "com.apple.system.kernel.unmount"
#define kNotifyVFSUpdate "com.apple.system.kernel.mountupdate"
#define kNotifyVFSLowDiskSpace "com.apple.system.lowdiskspace"
#define kNotifyVFSLowDiskSpaceRootFS "com.apple.system.lowdiskspace.system"
#define kNotifyVFSLowDiskSpaceOtherFS "com.apple.system.lowdiskspace.user"
/*
* System Configuration notifications
* These advise clients of changes in the system configuration
* managed by the system configuration server (configd).
* Note that a much richer set of notifications are available to
* clients using the SCDynamicStore API.
*/
#define kNotifySCHostNameChange "com.apple.system.hostname"
#define kNotifySCNetworkChange "com.apple.system.config.network_change"
/*
* ASL notifications
* Sent by syslogd to advise clients that new log messages have been
* added to the ASL database.
*/
#define kNotifyASLDBUpdate "com.apple.system.logger.message"
/*
* Time Zone change notification
* Sent by notifyd when the system's timezone changes.
*/
#define kNotifyTimeZoneChange "com.apple.system.timezone"
/*
* System clock change notification
* Sent when a process modifies the system clock using the settimeofday system call.
*/
#define kNotifyClockSet "com.apple.system.clock_set"
個人覺得里面kNotifyVFSLowDiskSpace,這個可以用來給app增加一個當(dāng)手機(jī)存儲空間很少的時候自動清理緩存的功能叨粘。對于網(wǎng)絡(luò)切換猾编,我們又多了一個監(jiān)聽方法。除了這些系統(tǒng)開放出來的升敲,網(wǎng)上還有不少私有的通知答倡,比如屏幕的亮度調(diào)節(jié),鎖屏的監(jiān)聽等等驴党。有興趣的可以看看其他的通知瘪撇。