iPhone NSURLConnection:connectionDidFinishLoading - 如何将字符串返回给调用方法
Posted
技术标签:
【中文标题】iPhone NSURLConnection:connectionDidFinishLoading - 如何将字符串返回给调用方法【英文标题】:iPhone NSURLConnection: connectionDidFinishLoading - how to return a string to the calling method 【发布时间】:2011-01-16 00:16:56 【问题描述】:我已经查看了类似的 *** 问题/答案,但我仍然感到困惑。
我是一个初学者,我真的很挣扎。使用 iPhone,我可以从 URL 下载 XML,但无法将结果字符串存储在 NSString 变量中并从调用函数中查看。
我在自定义类中有以下声明:
@interface comms : NSObject
NSString *currURL, *receivedString;
NSMutableData *receivedData;
NSURLConnection *conn;
@property (copy, readwrite) NSString *currURL;
@property (copy, readonly) NSString *receivedString;
@property (nonatomic, assign) NSMutableData *receivedData;
@property (nonatomic, assign) NSURLConnection *conn;
-(void) getContentURL;
我在 comms 类中有如下方法:
-(void) getContentURL
NSLog( @"Begin getContentURL." );
// Request data related.
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init]
autorelease];
[request setURL:[NSURL URLWithString: currURL]];
// Content-Type related.
[request setValue:@"application/x-www-form-urlencoded"
forHTTPHeaderField:@"Content-Type"];
// Create Connection.
conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (conn)
// The connection was established.
receivedData = [[NSMutableData data] retain];
NSLog( @"Data will be received from URL: %@", request.URL );
else
// The download could not be made.
NSLog( @"Data could not be received from: %@", request.URL );
// PROBLEM - receivedString is NULL here.
NSLog( @"From getContentURL: %@", receivedString );
我已按照以下内容在 comms 类中创建了所需的委托:
-(void)connection:(NSURLConnection *)connection didReceiveResponse:
(NSURLResponse *)response
// Discard all previously received data.
[receivedData setLength:0];
-(void)connection:(NSURLConnection *)connection didReceiveData:
(NSData *)data
// Append the new data to the receivedData.
[receivedData appendData:data];
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
// Connection succeeded in downloading the request.
NSLog( @"Succeeded! Received %d bytes of data", [receivedData length] );
// Convert received data into string.
receivedString = [[NSString alloc] initWithData:receivedData
encoding:NSASCIIStringEncoding];
NSLog( @"From connectionDidFinishLoading: %@", receivedString );
// release the connection, and the data object
[conn release];
[receivedData release];
我可以在 connectionDidFinishLoading 委托中使用 NSLog 成功输出 receivedString 字符串。
// Convert received data into string.
receivedString = [[NSString alloc] initWithData:receivedData
encoding:NSASCIIStringEncoding];
NSLog( @"From connectionDidFinishLoading: %@", receivedString );
但是,当我在 getContentURL 中输出 receivedString 字符串时,它为空(因此在我调用 comms 类的 ViewController.m 类中也为空)。
// PROBLEM - receivedString is NULL here.
NSLog( @"From getContentURL: %@", receivedString );
关于如何在 getContentURL 和 ViewController.m 类中查看 receivedString 值的任何想法?
【问题讨论】:
【参考方案1】:要从委托方法返回数据,请使用代码块。
见Apple's Blocks documentation。
【讨论】:
关于 OP 问题的代码很多,注意使用一些代码并显示示例吗?检查元how to provide a good answer 和有用的Jon Skeet blog【参考方案2】:NSURLConnection 是一个异步 API。当您启动请求时,该对象将产生一个新线程,并且仅通过回调/委托方法更新您的主线程。您当前的方法很可能会在请求完成之前返回,因此结果字符串还没有下载!
如果您想同步执行此操作,您将有两种选择:
-
使用内置的同步下载方法。请注意,由于这会阻塞,因此它不允许用户与 UI 交互。
使用 C 函数 CFRunLoopRun() 和 CFRunLoopStop() 在调用函数中启动运行循环,等待下载完成或失败,然后使用 CFRunLoopStop() 将控制权返回给调用方法。
【讨论】:
谢谢 chpwn,太好了!我现在已经实现了“同步下载”方法,因为它仍然是我们正在构建的原型。下周,我一定会实现“异步循环”方法。如果我在 getContentURL 方法中启动运行循环,这实际上可以让我将下载的数据保存到 receievedString 属性中吗? 基本上,它会做的是允许在不先退出该函数/消息的情况下调用回调。以上是关于iPhone NSURLConnection:connectionDidFinishLoading - 如何将字符串返回给调用方法的主要内容,如果未能解决你的问题,请参考以下文章
我们如何在 iPhone Xcode 中处理多个 NSURLConnection?
NSURLConnection 在 iphone 3gs 中发布大型视频数据失败
iPhone NSURLConnection:connectionDidFinishLoading - 如何将字符串返回给调用方法
NSURLSession/NSURLConnection HTTP 加载失败(kCFStreamErrorDomainSSL,-9813)错误不是在所有 iPhone 上?