I'm using NSLocalizedString in a particular message that works fine if the second parameter is passed as a variable, but fails with Use of undeclared identifier 'NSLocalizedString' and Too many arguments provided to function-like macro invocation if the second parameter is written exactly the same as the variable was set. I have working code using the variable, which is fine, I just want to understand the reasons for the failure to know how to avoid it in other situations.

With the following declarations:

NSString *branchTitle = [branchDictionary objectForKey:@"Title"];
NSString *localString = [NSMutableString stringWithFormat:@"%@ node title", branchTitle];

This works fine with no errors:

[navItem setTitle:NSLocalizedString(branchTitle, localString)];

... but this, which seems identical to me, fails with the errors noted above:

[navItem setTitle:NSLocalizedString(branchTitle, [NSMutableString stringWithFormat:@"%@ node title", branchTitle])];

Searching here and elsewhere I haven't found an explanation. I read through a number of hits on each error message and various NSLocalizedString issues, but nothing that tied them together. What I found about the second error message implied maybe an issue with clang and the number of commas in the statement, indicating that even though the extra comma is within the NSMutableString message, it was still being seen as an extra parameter by NSLocalizedString. Does that make any sense?

Not important for the question, but the statement is intended to set the localized version of a navigation bar title based on the English version pulled from a dictionary, which varies for different views. The NSMutableString portion defines the comment for the localization based on the English title.

EDIT: After resolving this issue per the accepted answer, below, I noticed another related issue. The declaration of localString was producing an "Unused variable" compiler warning, though it was clearly being used. This is also due to it being within a C-macro and for completeness, I'm adding a link to a relevant post here about suppressing that warning: How can I get rid of an “unused variable” warning in Xcode

有帮助吗?

解决方案

I believe this is a result of bad C-macro expansion. Indeed, if you write:

NSLocalizedString(branchTitle, ([NSString stringWithFormat:@"%@ node title", branchTitle]));

this will compile. For some reason, the preprocessor is not handling well the text within [] (possibly because it does not know about Objective-C calls) and treats all the elements within [] as separate arguments:

#define NSLocalizedString(key, comment) \
    [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]

PS: When I wrote bad C-macro expansion, I meant this:

Macro expansion is a tricky operation, fraught with nasty corner cases and situations that render what you thought was a nifty way to optimize the preprocessor's expansion algorithm wrong in quite subtle ways.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top