2012-09-03 83 views
0

我试图从服务器上为滚动视图拉图像。用户放大或缩小视图后,图像应下载:NSURLConnection委托方法不执行

- (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; 
} 
+4

如果您有任何关于'NSURLConnection'委托方法麻烦,请张贴有关这些代码,还有你的唯一的代码是'UIScrollView'委托方法。 –

回答

1

你为什么要显式调用CFRunLoopRun();connectionDidFinishLoading:didFailWithError:方法阻止它? (CFRunLoopStop(CFRunLoopGetCurrent());

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

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

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

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

我的建议在你的情况下将是使用dispatch_queue的重新设计的方法。这会让你更好地理解解决问题的方法(在这种情况下),同时也提高了你的代码可读性。

+0

它在后台线程上运行 – Shiim

+0

@Shiim你正在调用[self looYhendus];在scrollViewDelegate方法中,并且您正在使用该方法进行UIKit绘图。我没有看到你的代码在哪里产生线程。 – 0x8badf00d

+0

我很坏:(它在后台线程中运行时,我用它与CATiledLayer(这证明是由于某些原因不适合我的任务)。我删除了'CFRunLoopRun()'等,并添加了[[[CONNECT scheduleInRunLoop:[NSRunLoop [currentRunLoop] forMode:NSRunLoopCommonModes]; [theConnection start];'现在来自viewDidLoad的初始调用导致空白屏幕,虽然下载了图像,但相应的图像视图未设置为scrollviews子视图(将viewDidLoad添加到第一个帖子) 。它在缩放后被设置,但现在它应该是已缩放的图像,而不是最初的一个 – Shiim

1

我最近有同样的问题。问题在于,当连接已经异步时,我将连接放入异步线程中。

我发现这里的解决方案:NSURLConnection delegate methods are not called

也有其他人谁曾在该线程类似问题的几个环节。

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

例如:

[request setTimeoutInterval:30];