所以我试图动态构建一个字符串,我真的很喜欢构建这个字符串的所有代码都存在于作为参数传递给stringWithFormat
方法的块中。以下代码示例应该演示我尝试实现的目标:
NSString * deviceLanguage = [NSString stringWithFormat:@"Device Language: %@", ^NSString*(void){
NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
NSString *locale = [[NSLocale currentLocale] objectForKey: NSLocaleCountryCode];
return [NSString stringWithFormat:@"%@_%@", language, locale];
}];
预期的输出类似于......
Device Language: en_GB
但是,我从这个方法获得的输出实际上返回了NSGlobalBlock方法的description
,例如
Device Language: <__NSGlobalBlock__:0x30a35c>
这是因为我没有在字符串中使用正确的占位符,或者没有声明该块返回NSString
个对象吗?
答案 0 :(得分:6)
那是因为你将块本身作为参数传递给stringWithFormat:
,
而不是调用块的结果:
NSString * deviceLanguage = [NSString stringWithFormat:@"Device Language: %@", ^NSString*(void){
NSLocale *locale = [NSLocale currentLocale];
NSString *language = [locale displayNameForKey:NSLocaleIdentifier
value:[locale localeIdentifier]];
return [NSString stringWithFormat:@"%@_%@", language, locale];
}()];
请注意,您可以使用"compound statement expression"获得类似的结果 而不是一个块:
NSString * deviceLanguage = [NSString stringWithFormat:@"Device Language: %@", ({
NSLocale *locale = [NSLocale currentLocale];
NSString *language = [locale displayNameForKey:NSLocaleIdentifier
value:[locale localeIdentifier]];
[NSString stringWithFormat:@"%@_%@", language, locale];
})];
答案 1 :(得分:1)
这是一个很好的问题!
问题出在stringWithFormat:
。当它处理它的格式字符串时,当它到达%@
时,它会找到对象参数,在其上调用-description
并将对象的描述添加到其中输出。这种情况下的描述是<__NSGlobalBlock__:0x30a35c>
你可以通过以下方式解决这个问题:
NSString*(^userLanguage)(void) = ^(void) {
NSLocale *locale = [NSLocale currentLocale];
NSString *language = [locale displayNameForKey:NSLocaleIdentifier
value:[locale localeIdentifier]];
return [NSString stringWithFormat:@"%@_%@", language, locale];
};
NSString *language = userLanguage();
NSString * deviceLanguage = [NSString stringWithFormat:@"Device Language: %@", language];
但当然你现在不需要这个块,所以你可以这样做:
NSLocale *locale = [NSLocale currentLocale];
NSString *language = [locale displayNameForKey:NSLocaleIdentifier
value:[locale localeIdentifier]];
NSString *userLanguage = [NSString stringWithFormat:@"%@_%@", language, locale];;
NSString * deviceLanguage = [NSString stringWithFormat:@"Device Language: %@", userLanguage];
答案 2 :(得分:1)
因为您正在将块对象传递给stringWithFormat
:所以您正在打印描述。如在@MartinR答案。
如果您按照这样重新编码,就可以更轻松地管理您的块。
// first you declare a block like this, to retain it or pass it multiple times
typedef NSString* (^MyBlock)(void);
MyBlock block = ^{
NSLocale *locale = [NSLocale currentLocale];
NSString *language = [locale displayNameForKey:NSLocaleIdentifier
value:[locale localeIdentifier]];
// print the local id
return [NSString stringWithFormat:@"%@_%@", language, locale.localeIdentifier];
};
// Now pass it to stringWithFormat:
NSString *deviceLanguage = [NSString stringWithFormat:@"device language: %@", block()];