我有一个登录方法。在方法内部我使用NSURLConnection登录,我想返回NSData响应。问题是我在连接实际获取数据之前返回NSData。
- (NSData*)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[responseData appendData:data]; //responseData is a global variable
NSLog(@"\nData is: %@", [[[NSString alloc] initWithData:responseData
encoding:NSUTF8StringEncoding]autorelease]);//this works
isLoaded = YES; //isLoaded is a BOOL
}
- (NSData*)login:(NSString*)username withPwd:(NSString*)password{
isLoaded = NO;
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request
delegate:self];
if(connection){
NSLog(@"Connected");
}
while(isLoaded = NO){
[NSThread NSSleepForTimeInterval: 1];
}
isLoaded = NO;
return responseData;
}
程序在while循环中停滞不前,但是如果没有while循环,程序可以从服务器检索数据,只是该方法似乎在委托方法更改之前返回responseData。
所以我的问题是如何才能使它成为只有在服务器完成后才返回responseData的方法?
答案 0 :(得分:1)
除非另有说明,否则NSURLConnection会异步加载URL。它使用deleegate回调来更新有关URL下载进度的委托。
具体来说,使用NSURLConnection委托的connectionDidFinishLoading:方法。一旦加载了所有数据,您的NSURLConnection对象将调用此对象。您可以在此方法中返回数据。
您可以同步加载数据,但最终可能会阻止用户界面。
祝你好运!答案 1 :(得分:1)
你应该重构你的代码。
您正在使用异步调用(很好),但是您尝试同步处理它(不太好 - 如果不使用单独的线程)。
要使用异步行为,你需要一个回调,在cocoa-style中,这通常是一个委托方法(或者可以是一个新代码的块)。实际上这是你的connection:didReceiveData
。此方法将与返回的数据一起使用 - 而不是您启动请求的那个数据。因此,通常启动异步请求的方法不会返回任何内容 - 当然也不会返回请求返回的内容。
- (void)login:(NSString*)username withPwd:(NSString*)password
{
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
//Note: you cannot change the delegate method signatures, as you did (your's returns an NSData object)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[self.responseData appendData:data]
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//Now that the connection was successfully terminated, do the real work.
}
看看这个apple example code。
答案 2 :(得分:0)
您可以使用同步请求方法
- (NSData*)login:(NSString*)username withPwd:(NSString*)password
{
NSError *error = nil;
NSURLResponse *response = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]
return responseDate;
}