NSURLConnection委托方法不执行

时间:2012-09-03 19:32:24

标签: ios nsurlconnection scrollview

我正在尝试从服务器中为scrollview提取图像。用户放大或缩小视图后,应下载图像:

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {

Ymin=365000+375000*_scrollView.contentOffset.x/(scale*1024);
Ymax=365000+375000*(_scrollView.contentOffset.x/scale+1024/scale)/1024;
Xmin=6635000-260000*(_scrollView.contentOffset.y/scale+748/scale)/748;
Xmax=6635000-260000*_scrollView.contentOffset.y/(scale*748);

[self looYhendus];  //Creates NSURLConnection and downloads the image according to scale, Ymin, Ymax, Xmin and Xmax values

UIImage *saadudPilt=_kaardiPilt;
imageView=[[UIImageView alloc] initWithImage:saadudPilt];
imageView.frame=CGRectMake(_scrollView.contentOffset.x,_scrollView.contentOffset.y,1024,748);
[_scrollView addSubview:imageView];

}

在某些情况下(我无法弄清楚,在什么条件下),它有效,但在某些情况下NSURLConnection委托方法不会被触发,并且设置为子视图的图像仍然是最初下载的图像(当应用程序启动时)。然后,只有在我再次触摸屏幕(滚动视图滚动)后,NSLog消息才会显示图像已下载。这种行为可能是什么原因?

编辑:添加了NSURLConnection委托方法。我尝试过其他一些方法,但最终都没有执行委托方法。这让我觉得它不是关于NSURConnection而是关于UIScrollView(显然,我可能错了)。

- (void)looYhendus
{   
yhendused=CFDictionaryCreateMutable(
                                    kCFAllocatorDefault, 
                                    0,
                                    &kCFTypeDictionaryKeyCallBacks,
                                    &kCFTypeDictionaryValueCallBacks);

NSString *aadress = [NSString stringWithFormat:@"http://xgis.maaamet.ee/wms-pub/alus?version=1.1.1&service=WMS&request=GetMap&layers=MA-ALUSKAART&styles=default&srs=EPSG:3301&BBOX=%d,%d,%d,%d&width=%d&height=%d&format=image/png",Ymin,Xmin,Ymax,Xmax,512,374];
NSURL *url = [[NSURL alloc] initWithString:aadress];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

if( theConnection )
{
    andmedServerist = [NSMutableData data];
    CFDictionaryAddValue(
                         yhendused,
                         (__bridge void *)theConnection,
                         (__bridge_retained CFMutableDictionaryRef)[NSMutableDictionary
                                                                    dictionaryWithObject:[NSMutableData data]
                                                                    forKey:@"receivedData"]);
}
CFRunLoopRun();
}

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[andmedServerist setLength: 0];
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSMutableDictionary *connectionInfo =
(NSMutableDictionary*)objc_unretainedObject(CFDictionaryGetValue(yhendused, (__bridge void *)connection));
[[connectionInfo objectForKey:@"receivedData"] appendData:data];

}

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Ühenduse viga" message:@"Kõige tõenäolisemalt on kaardiserveril probleeme või puudub seadmel internetiühendus" delegate:self cancelButtonTitle:@"Sulge" otherButtonTitles:nil];
[alert show];
CFRunLoopStop(CFRunLoopGetCurrent());
}


-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSMutableDictionary *connectionInfo =
(NSMutableDictionary*)objc_unretainedObject(CFDictionaryGetValue(yhendused, (__bridge void *)connection));
[connectionInfo objectForKey:@"receivedData"];
andmedServerist=[connectionInfo objectForKey:@"receivedData"];

_kaardiPilt = [UIImage imageWithData: andmedServerist];
CFDictionaryRemoveValue(yhendused, (__bridge void *)connection);

CFRunLoopStop(CFRunLoopGetCurrent());

}

编辑:补充一下:

- (void)viewDidLoad
{
[super viewDidLoad];
Ymin=365000;
Ymax=740000;
Xmin=6375000;
Xmax=6635000;
[self looYhendus];
UIImage *saadudPilt=_kaardiPilt;
imageView=[[UIImageView alloc] initWithImage:saadudPilt];
imageView.frame=CGRectMake(0,0,1024,748);
[_scrollView addSubview:imageView];
[_scrollView setContentSize: CGSizeMake(1024, 748)];
_scrollView.minimumZoomScale = 1.0;
_scrollView.maximumZoomScale = 50.0;
_scrollView.delegate = self;
}

2 个答案:

答案 0 :(得分:1)

为什么要明确调用CFRunLoopRun();并在connectionDidFinishLoading:didFailWithError:方法中将其停止? (CFRunLoopStop(CFRunLoopGetCurrent());

假设您在主线程上执行此操作。你正在停止mainthread的runloop。可以有计时器,ScrollView使用停止响应的事件,因为你停止了主线程的runloop。

如果您在主线程上调用NSURLConnection,则不需要显式运行它(或停止它)。你可以安排在当前的runloop上运行,这是主线程runloop。如果您在后台线程上执行此操作,那么您的代码似乎是有效的(尽管如果在UIAlertView中调用单独的线程,则不应显示didFailWithError:。)

更新的答案(基于@ Shiim的评论):

viewDidLoad方法中,您正在调用[self looYhendus];,它会立即返回(因为您正在使用负载的异步URL连接)。所以它按预期工作。将[scrollView addSubview:imageView]移动到connectionDidFinishLoading:方法,将下载后的imageView数据添加到scrollView的子视图中。或者您可以考虑使用dispatch_queue创建一个线程并同步加载URL请求,然后使用dispatch_queue的主队列将作为subView添加的imageView图形调度到ScrollView到主线程上。

我的建议是使用dispatch_queue重新设计的方法。这将使您更好地理解解决问题(在此方案中),并提高您的代码可读性。

答案 1 :(得分:1)

我最近遇到了同样的问题。问题是,当连接已经异步时,我将我的连接放在异步线程中。

我在这里找到了解决方案:NSURLConnection delegate methods are not called

还有一些链接指向该主题中有类似问题的其他人。

如果我是你,我会尝试简单地使用[theConnection start]并使用设置超时初始化请求,这样您就不必担心在下载图像之前后台线程关闭了。

例如:

[request setTimeoutInterval:30];