objective c 缺少 _block 类型说明符

objective c missing _block type specifier

这里是 objective c 的新手......我正在尝试初始化 2 个字符串并稍后设置它们,但是我在 r1 和 r2 上遇到了这个错误:

the variable is not assignable (missing _block type specifier)

我的代码如下所示:

    NSMutableString *r1 = [NSMutableString stringWithFormat:@"None"];
    NSMutableString *r2 = [NSMutableString stringWithFormat:@"None"];
    NSURLRequest *request = [client URLRequestWithMethod:@"GET" URL:statusesShowEndpoint parameters:params error:&clientError];

if (request) {
    [client sendTwitterRequest:request completion:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        if (data) {
            // handle the response data e.g.
            NSError *jsonError;
            NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
            NSLog(@"ok!");
            for(NSString *key in [json allKeys]) {
                NSLog(@"%@",key);
            }
            r1 = json[@"statuses"][0][@"text"];
            r2 = json[@"statuses"][1][@"text"];

我很困惑这是否是设置字符串的正确方法.... 就像我想做的就是初始化一个字符串并稍后设置它。

您对两个字符串变量的赋值位于您传递给 sendTwitterRequest:completion: 的块内。默认情况下,块捕获它在块外声明的任何局部变量的 value,在您的情况下 r1r2,它不会捕获变量本身,这意味着它不能改变存储在这些变量中的值。请注意,如果捕获的 value 是对可变对象的引用,在您的情况下,值是对可变字符串的引用,那么您可以改变对象 - 这样做不会改变引用本身.

您可以通过两种方式修复代码:

1) 我认为您尝试分配的值是对不可变字符串 NSString * 的引用,因此我怀疑您只是将这两个变量声明为 NSMutableString * 以试图修复您的问题问题。

要允许对捕获的局部变量赋值,您必须使用 __block 注释局部变量声明,这会更改行为捕获,以便 变量 ,而不是它的 ,被捕获。要走这条路,您只需将声明更改为:

__block NSString *r1;
__block NSString *r2;

不需要给变量赋初始值,它们会自动取值nil。您的块现在可以直接分配给 r1r2,但是请参阅下面的 BIG BUT。

2) 如果你确实需要可变字符串,NSMutableString *,那么你的两个声明都很好,问题是你使用了变量赋值 (r1 & r2)而不是改变他们引用的字符串。您可以使用 setString: 更改可变字符串的值(Apple documentation。为此,请将您的两个赋值替换为:

[r1 setString:json[@"statuses"][0][@"text"]];
[r2 setString:json[@"statuses"][1][@"text"]];

这两个将改变变量引用的字符串,并且这些更改将通过存储在 r1r2 中的引用在您的块外可见。然而,与上面的第一种方法一样,请参阅以下大但...

大但是

您提供的代码片段表明您可能还犯了一个常见错误:假设在调用块后,用作异步处理程序的块中分配的值将可见,在您的情况下 sendTwitterRequest:completion:。这通常 not 为真,调用 sendTwitterRequest:completion: returns before 完成块有 运行 - 这是异步方法的全部要点,例如 sendTwitterRequest:completion:;他们在后台同时安排工作(在你的情况下是 accessingTwitter)到 运行,然后是 return,稍后当异步工作完成时,调用完成块。

如果你犯了这个错误,你需要阅读异步设计,如果你愿意,你可以使用 Apple 的文档,你也可以在 SO 上搜索 - 有很多关于这个主题的问答。完成后,您可以重新设计代码,如果此时遇到问题,请提出新问题。

HTH