NSURLConnection 只工作一次
我开发我的第一个应用程序已经有一段时间了,但似乎我在这里遗漏了一些东西。下面的代码最初仅在我的应用程序委托中;我刚刚在第一个视图控制器中添加了一个刷新按钮,以便刷新应用程序使用的数据,所以我的第一个想法是在视图控制器内再次调用应用程序委托代码,但是 NSURLConnection
委托方法没有开火。现在,我已将代码添加到视图控制器(并将其保留在应用程序委托中),并且按下刷新按钮时会触发委托方法,但 responseData
为 null,refreshString 为空,并且
JSONValue
在日志中抛出“意外的输入结束”错误(因为没有输入任何内容)(应用程序仍然运行并清除 UITableView,这是正确的行为,因为数组是现在是空的)。 JSON数据的字符集是UTF-8
这段代码可能有一个更好的地方,可以将其保存在一个地方并根据需要运行,如果有任何相关建议,我也会很感激,但我主要关心的是正在弄清楚为什么这段代码第一次工作正常,但第二次就不起作用。
- (void) refreshData{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://beersandears.net/beer-list-json.php?native=yes"]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
NSLog(@"loadData complete");
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[responseData setLength:0];
NSLog(@"Response received");
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[responseData appendData:data];
NSLog(@"Data received");
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[connection release];
//label.text = [NSString stringWithFormat:@"Connection failed %@", [error description]];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
connection = nil;
NSString *refreshString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
[responseData release];
NSDictionary *results = [refreshString JSONValue];
BeerListAppDataObject* theDataObject = [self beerListAppDataObject];
[theDataObject.beerList removeAllObjects];
[theDataObject.mapList removeAllObjects];
[theDataObject.blogList removeAllObjects];
theDataObject.beerList = [results objectForKey:@"beer"];
theDataObject.mapList = [results objectForKey:@"map"];
theDataObject.blogList = [results objectForKey:@"blog"];
NSLog(@"Data Loaded");
[self.tableView reloadData];
}
I have been working on my first app for some time now, but it seems that I am missing something here. The code below was originally only in my app delegate; I just added a refresh button in the first view controller in order to refresh the data the app uses, so my first idea was to call the app delegate code again inside the view controller, but the NSURLConnection
delegate methods did not fire. Now I have added the code to the view controller (and also kept it in the app delegate) and the delegate methods fire when the refresh button is pressed, but responseData
is null, refreshString
is empty and JSONValue
throws an "Unexpected end of input" error (because nothing is being inputted) in the log (the app still runs and clears the UITableView, this is proper behavior since the array is now empty). The JSON data's character set is UTF-8
There may be a better place for this code where it can be kept in one place and run as needed, and if there are any suggestions regarding that I would appreciate them as well, but my primary concern is figuring out why this code works correctly the first time, but does not work the second.
- (void) refreshData{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://beersandears.net/beer-list-json.php?native=yes"]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
NSLog(@"loadData complete");
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[responseData setLength:0];
NSLog(@"Response received");
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[responseData appendData:data];
NSLog(@"Data received");
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[connection release];
//label.text = [NSString stringWithFormat:@"Connection failed %@", [error description]];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
connection = nil;
NSString *refreshString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
[responseData release];
NSDictionary *results = [refreshString JSONValue];
BeerListAppDataObject* theDataObject = [self beerListAppDataObject];
[theDataObject.beerList removeAllObjects];
[theDataObject.mapList removeAllObjects];
[theDataObject.blogList removeAllObjects];
theDataObject.beerList = [results objectForKey:@"beer"];
theDataObject.mapList = [results objectForKey:@"map"];
theDataObject.blogList = [results objectForKey:@"blog"];
NSLog(@"Data Loaded");
[self.tableView reloadData];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您正在 finishLoading 中释放 NSData responseData 成员变量:
但是,我没有看到任何其他内容可以附加另一个 NSData 对象。
在此示例代码中:
http:// developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html
当他们启动连接时, 再次(在您的刷新方法中),他们这样做:
关键是他们获取 NSMutabaleData 对象并保留它。
You're releasing the NSData responseData member variable in finishLoading:
But, I don't see anything else getting another NSData object to append.
In this sample code here:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html
when they start the connection again (in your refreshMethod), they do:
The key line being this where they get an NSMutabaleData object and retain it.
只是猜测:尝试检查responseData NSMutableData 变量是否已在视图控制器中正确初始化。
即使这解决了眼前的问题,最好将此代码抽象为它自己的类(也许是“BeerAPIClient”类?),这样它就不必存在于两个地方。这样,随着它的增长和变化,维护起来会更容易,因为只有一个地方可以更新。
Just a guess: try checking that the responseData NSMutableData variable has been properly initialized in the view controller.
Even if that solves the immediate problem, it would be good to abstract this code out into its own class (a "BeerAPIClient" class, perhaps?) so it does not have to exist in two places. That way, it is easier to maintain as it grows and changes because there only one place to update.