3

我在一個庫中的方法,看起來像這樣的objc方法:如何將數組傳遞給需要變參(如...')

- (id)initWithSomeObjects:(NSString *)something, ... NS_REQUIRES_NIL_TERMINATION; 

我真的很喜歡叫它用一個數組而不是var args,因爲我想要傳遞的對象的數量是可以改變的。

有沒有辦法,使用performSelector或NSInvocation或objc_msgSend或其他什麼,我可以調用var args方法,參數來自數組?

+0

我在這裏找到了一種方法,但它不能在xcode4 +下編譯 - http://www.cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html – Chris

+0

什麼是編譯錯誤? – Wain

+2

該程序不會做你想做的。這是將'NSArray'的內容傳遞給'va_list'。你的方法不需要'va_list',它需要可變數目的參數。一個'va_list'是它自己的類型 - 只是一個字節緩衝區,但它是一個單獨的參數。你的方法看起來像' - (id)initWithSomeObjects:(va_list)objs'比較' - [NSString initWithFormat:]'和' - [NSString initWithFormat:arguments:]'。 –

回答

5

有沒有簡單的方法來做到這一點,因爲如何傳遞參數進入特定系統的調用ABI的醜陋的細節,你必須知道例如有多少參數被放入寄存器,以及如何處理剩餘的參數等。這將涉及彙編,並且不能以一般方式完成。

通常,其具有可變參數需要像這樣,也將或者

  1. 提供另一種採用一個va_list參數,而不是(例如-[NSString initWithFormat:]具有-[NSString initWithFormat:arguments:])方法的方法或功能的任何API。如果是這種情況,那麼您可以使用該技巧從您鏈接到的評論文章中構建va_list。 (即使構建的va_list是系統特定且不可移植的,但至少它可以在Mac和iPhone上工作,並且它相當簡單,並且不涉及彙編。)
  2. 提供另一種方法,它需要一個NSArray *或一個C數組的元素(例如-[NSArray initWithObjects:]-[NSArray initWithObjects:count:]
  3. 有方法逐個添加元素,使得總體效果與將它們一起傳遞給可變參量方法相同(例如,可以實現-[UIAlertView initWithTitle:message:delegate:cancelButtonTitle:otherButtonTitles:]末尾的可變長按鈕標題通過多次呼叫-[UIAlertView addButtonWithTitle:])。

如果你有一個可變varargs API沒有上述的API之一,那麼這是一個糟糕的API設計,你應該抱怨誰寫的。如果你真的遇到這種情況,我猜測可能會使用像libffi這樣的東西,它允許你動態地調用函數,並且處理依賴於系統的調用機制的基本特性。

相關問題