Objective-C新手求助:变量不可赋值(缺失_block类型说明符)问题
解决Block中无法修改外部变量的问题
嘿,我来帮你搞定这个问题!你遇到的“变量不可赋值(缺失_block类型说明符)”错误,是Objective-C Block的常见特性导致的,另外还有字符串类型匹配的小细节需要注意,咱们一步步理清楚:
为什么会报错?
在Objective-C中,Block默认会捕获外部局部变量的副本,而不是直接引用变量本身。这意味着你在Block里无法直接修改外部局部变量的指针(比如你这里的r1和r2)。要让Block能修改外部变量,必须在变量声明前加上__block修饰符。
字符串赋值的小细节
另外要注意:json[@"statuses"][0][@"text"]返回的是NSString类型对象,而你声明的r1、r2是NSMutableString。如果直接赋值r1 = json[...],相当于把r1的指针从原来的NSMutableString对象指向了一个NSString对象,原来的可变字符串会被释放。如果你需要保持可变字符串的特性,应该用setString:方法更新内容,而不是直接赋值指针。
修改后的代码示例
情况1:只是需要保存字符串内容(不需要保持可变)
如果不需要r1、r2是可变的,可以直接把它们声明为NSString,加上__block修饰:
__block NSString *r1 = @"None"; __block NSString *r2 = @"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) { 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"]; } }]; }
情况2:需要保持NSMutableString的可变特性
如果必须用NSMutableString,不要直接赋值指针,而是用setString:方法更新内容,同时也要加上__block修饰(方便后续继续修改这个可变字符串):
__block NSMutableString *r1 = [NSMutableString stringWithFormat:@"None"]; __block 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) { NSError *jsonError; NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError]; NSLog(@"ok!"); for(NSString *key in [json allKeys]) { NSLog(@"%@",key); } // 用setString:更新可变字符串的内容,加默认值防止nil NSString *text1 = json[@"statuses"][0][@"text"]; [r1 setString:text1 ?: @"None"]; NSString *text2 = json[@"statuses"][1][@"text"]; [r2 setString:text2 ?: @"None"]; } }]; }
补充说明
__block修饰符的作用是让变量成为Block可以引用和修改的“共享变量”,而不是捕获副本。- 如果你只是在Block里读取变量,不需要
__block;但修改变量指针(比如把r1指向新对象)需要加__block,而修改可变对象的内部状态(比如给NSMutableArray添加元素)则不需要,因为你只是修改对象本身的内容,不是改变指针指向。
内容的提问来源于stack exchange,提问作者J.Titor.0
相关产品推荐
相关产品推荐

