2009-11-25 24 views
3

我使用NSLog()將某些內容打印到控制檯。有沒有辦法將所有當前方法的參數傳遞給NSLog()或任何其他函數或方法,而不顯式地查看它們中的每一個?將方法的所有參數傳遞給NSLog

例如,我已經有了一個宏,它可以在我的代碼中放入LOGME時,將有用的信息輸出到控制檯。宏將創建一個對單例類的日誌記錄方法的調用,並傳遞一些有用的東西,如_cmd和其他東西。

我也想捕獲該方法的所有參數,並將它們傳遞給自動打印出來。那可能嗎?

回答

3

使用gdb。您可以設置一個將參數記錄到方法並繼續的斷點。

如果你堅持要這麼做的話......這當然不簡單,但是你可以在給定的體系結構/ ABI上使用堆棧結構,並利用Objective-C運行時來找出有多少個參數和要尋找什麼尺寸。從這裏開始,我處於未知領域;我從來沒有這樣做,也不會打擾。所以YMMV ...

在你的方法中,你可以得到結構,然後是參數個數,然後是每個參數類型和它的大小。然後,您可以漫步在堆棧從self參數(即&self)的地址,假設你知道你在做什麼?

Method method = class_getInstanceMethod([self class], _cmd); 
unsigned nargs = method_getNumberOfArguments(method); 
void *start = &self; 
for(unsigned i = 0; i<nargs; i++) { 
    char *argtype = method_copyArgumentType(method, i); 
    //find arg size from argtype 
    // walk stack given arg zie 
    free(argtype); 
} 

沿途你將不得不從argtype字符串轉換的方式(使用Objective-C type encodings)與堆棧上每個參數的大小。

當然,你必須得到每種類型的格式字符串,並且用包含參數的適當的變量參數數組調用NSLogv,從它們在堆棧上的位置複製它們。可能比它的價值更多的工作。使用調試器。

+0

難道你不想要'self'變量的地址嗎?從*中的對象指針*開始,'self'變量不打印方法的參數;它將打印對象的實例變量(可能是垃圾,因爲您將使用方法參數類型來指導錯誤)。 – 2009-11-26 02:47:20

+0

是的,絕對,從&自我開始。 – 2009-11-26 03:52:08

+0

這就是我的意思:不應該'開始'初始化爲'&self',而不是'self'? – 2009-11-30 03:46:20

3

無法解決預處理器或Objective-C中的所有參數。

我知道的唯一方法就是使用調試器。您可以在Xcode中添加斷點操作以輕鬆完成此操作。右鍵單擊代碼窗口的最左邊一列,選擇「內置斷點」 - >「記錄斷點和參數並自動繼續」。

+0

調試器是如何做到的? – 2009-11-25 16:55:40

+3

調試器擁有關於ABI(調用約定)的知識並使用調試符號(由編譯器創建)來映射代碼中的地址並將其註冊到源文件中的位置和變量。簡而言之:它使用了一大堆技巧,它們不屬於該語言的一部分。 – 2009-11-25 17:11:02