我有以下代码
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:SOMEURL];
NSError *err;
NSData *response = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:nil error:&err];
if (err)
{
// Do some error stuff
}
err = nil;
NSDictionary *downloadedDictionary = [NSJSONSerialization JSONObjectWithData:response options:0 error:&err];
if (err)
{
// Do some error stuff
}
dispatch_sync(dispatch_get_main_queue(), ^{
NSDictionary* item = [downloadedDictionary objectForKey:@"user"];
NSString* name = [item valueForKey:@"name"];
[txtName setText:name];
});
});
但是我每次都在[txtName setText:name]上崩溃。 txtName在标题中设置并正确合成。事实上,如果我做[txtName setText:@“随机文本”]它的工作正常。我也可以做NSLog(@“%@”,名称),它会记录信息。就在我尝试将两者混合在一起时,它崩溃了。有任何想法吗?我的错误是
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI length]: unrecognized selector sent to instance 0x109c66bd0'
答案 0 :(得分:1)
试试这个,并确保在例外情况下有一个Xcode断点:
dispatch_sync(dispatch_get_main_queue(), ^{
assert(store);
assert([store isKindOfClass:[NSDictionary class]]);
NSString* name = [store valueForKey:@"name"];
assert(name);
assert([name isKindOfClass:[NSString class]]);
assert([self.txtName isKindOfClass:[UITextField class]]);
[self.txtName setText:name]; // note the user of "self"
});
答案 1 :(得分:0)
通过跳回主队列以更新UIKit对象,您已经完成了正确的操作。正如您可能从文档中注意到的那样,UIKit通常不能安全地用于后台线程或队列,但有一些例外情况,Apple会以相当混乱的特殊方式提及。
话虽如此,[store valueForKey:@"name"]
似乎是一个数组,而不是一个字符串。因此,您的错误是无法验证和/或正确解析返回的JSON。如果你NSLog
它(或者,如果你想确定[name class]
),你应该看到它。
同样,如果你检查JSON,你可能会在结果周围看到方括号。
您可能需要以下内容:
NSString *name = nil; // or don't bother with "= nil" if using ARC
NSArray *names = [store valueForKey:@"name"];
if([names isKindOfClass:[NSArray class]] && [names count] > 0)
name = names[0];
if(name)
[txtName setText:name];
假设您只期待一个名字。这两个if
用作验证,Objective-C完全遵循条件评估的C规则 - 如果isKindOfClass:
失败,那么对count
的调用将永远不会发生,因此它是安全的测试条件一侧的类型,然后在另一侧假设它。