【问题标题】:objective c missing _block type specifier目标c缺少_block类型说明符
【发布时间】:2018-01-27 06:46:13
【问题描述】:

这里是目标 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"];

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

【问题讨论】:

  • 您的错误表明您包含的代码没有包含足够的上下文供人们验证您的问题。这两个任务究竟在哪里?编辑您的问题以提供更多背景信息,以便人们可以更好地帮助您。
  • 不清楚,缺少信息,但如果我在这里猜测,我会说你有一个带有块的 NSURLSession 的异步调用,你想检索一些值到 r1r2,它们是在块之前声明的,因此您需要改为 __block NSString *r1。见那里:stackoverflow.com/questions/7080927/… 另外,你定义它的方式是可变的,但我强烈认为json[@"statuses"][0][@"text"] 并不是真正可变的,是NSString 而不是NSMutableString

标签: objective-c xcode nsstring


【解决方案1】:

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

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

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

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

__block NSString *r1;
__block NSString *r2;

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

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

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

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

大但是

您提供的代码片段表明您可能还犯了一个常见错误:假设在用作异步处理程序的块中分配的值将在调用块后可见,在您的情况下为sendTwitterRequest:completion:。这通常为真,对sendTwitterRequest:completion: 的调用返回完成块运行之前 - 这是异步方法的全部意义,例如sendTwitterRequest:completion:;他们安排工作(在您的情况下访问Twitter)在后台并发运行,然后返回,稍后当异步工作完成时调用完成块。

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

HTH

【讨论】:

  • 它解决了我遇到的错误......但是当我将 label.text 设置为 r1 或 r2 时,我得到了 none 或 null。这是否意味着我必须将 NSMutableString 更改为 NSString?
  • 我怀疑这意味着您已经与“大但是”发生冲突,并且在异步块写入变量之前正在读取它。
  • 感谢您的帮助和澄清 :-) 这对我有很大帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-02
  • 1970-01-01
相关资源
最近更新 更多