Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/101.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 使用块的返回值动态创建字符串_Ios_Objective C_String_Objective C Blocks - Fatal编程技术网

Ios 使用块的返回值动态创建字符串

Ios 使用块的返回值动态创建字符串,ios,objective-c,string,objective-c-blocks,Ios,Objective C,String,Objective C Blocks,因此,我试图动态地构建一个字符串,我真的希望构建这个字符串的所有代码都存在于作为参数传递给stringWithFormat方法的块中。以下代码示例应演示我试图实现的目标: NSString * deviceLanguage = [NSString stringWithFormat:@"Device Language: %@", ^NSString*(void){ NSString *language = [[NSLocale preferredLanguages] ob

因此,我试图动态地构建一个字符串,我真的希望构建这个字符串的所有代码都存在于作为参数传递给
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方法的
描述
,例如

Device Language: <__NSGlobalBlock__:0x30a35c>
设备语言:

这是因为我没有在字符串中使用正确的占位符,还是没有声明块返回一个
NSString
对象?

这是一个好问题

问题出在
stringWithFormat:
中。在处理其格式字符串时,当它到达
%@
时,它会找到对象参数,对其调用
-description
,并将对象的描述添加到其输出中。本例中的描述为

您可以通过以下操作来解决此问题:

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];

这是因为您将块本身作为参数传递给
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];

}()];
请注意,使用 而不是块:

NSString * deviceLanguage = [NSString stringWithFormat:@"Device Language: %@", ({

    NSLocale *locale = [NSLocale currentLocale];
    NSString *language = [locale displayNameForKey:NSLocaleIdentifier
                         value:[locale localeIdentifier]];
    [NSString stringWithFormat:@"%@_%@", language, locale];

})];

因为要将块对象传递给
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()];

感谢您的回答,这很有意义,但是我试图将所有内容都保存在一条语句中,以获得干净的代码,因此我将接受Martin的回答,但这同样有效。你对它失败的确切原因的解释非常有用。但愿我能接受这两个答案<代码>对于干净的代码是有争议的:P在大多数情况下,我更喜欢方法调用而不是复合语句。你可能是对的,我只是喜欢这样一种想法,即在创建字符串的方法中(实际上)可以看到字符串构造的所有内容,但我只是在尝试块。谢谢,这正是我想要的。我以前从未遇到过复合语句表达式,这看起来非常有用!在第一种情况下,只需写入[NSString stringWithFormat:@“设备语言:%@,^{…}()];这让我感觉好多了,我错过的只是实际执行块的最后一个()!谢谢,我忘了你应该
typedef
像这样的重要块。@Sammio2,也请看我打印的是locale.localeIdentifier,而不是locale,以获得所需的结果。我确实注意到了,谢谢。此后,我意识到,我所寻找的实际信息可以通过以下简单的代码获得:
[[NSLocale preferredLanguages]objectAtIndex:0]
使整个问题无效,但它教会了我一些关于块的知识!