0

スクロールビュー用にサーバーから画像をプルしようとしています。ユーザーがビューをズームインまたはズームアウトした後、画像をダウンロードする必要があります。

- (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

2 に答える 2

1

またはメソッドで明示的に呼び出しCFRunLoopRun();て停止するのはなぜですか?()connectionDidFinishLoading:didFailWithError:CFRunLoopStop(CFRunLoopGetCurrent());

これをメインスレッドで実行していると仮定します。メインスレッドの実行ループを停止しています。タイマーが存在する可能性があります。ScrollViewは、メインスレッドの実行ループを停止したために応答を停止するイベントを使用します。

メインスレッドを呼び出しNSURLConnectionている場合は、明示的に実行(または停止)する必要はありません。メインスレッドのrunloopである現在のrunloopで実行するようにスケジュールすることができます。バックグラウンドスレッドで実行している場合、コードは有効であるように見えます(ただし、別のスレッドで呼び出された場合は表示UIAlertViewしないでくださいdidFailWithError:)。

更新された回答(@Shiimのコメントに基づく):

viewDidLoad呼び出しているメソッドで、[self looYhendus];すぐに戻ります(ロードに非同期URL接続を使用しているため)。したがって、期待どおりに機能します。ダウンロードが完了したら、ダウンロードしたimageViewデータをscrollViewのsubViewに追加するメソッドに移動[scrollView addSubview:imageView]します。connectionDidFinishLoading:または、を使用dispatch_queueしてスレッドを作成し、URLリクエストを同期的にロードしてから、dispatch_queueメインキューを使用して、サブビューとして追加されたimageViewの描画をScrollViewにメインスレッドにディスパッチすることを検討できます。

あなたの場合の私の推奨は、dispatch_queueを使用して再設計されたアプローチです。これにより、(このシナリオで)問題を解決するための理解が深まり、コードの可読性も向上します。

于 2012-09-03T20:45:06.060 に答える
1

私は最近同じ問題を抱えていました。問題は、接続がすでに非同期であるときに、接続を非同期スレッドに入れていたことでした。

私はここで解決策を見つけました:NSURLConnectionデリゲートメソッドは呼び出されません

そのスレッドで同様の問題を抱えていた他の人々へのリンクもいくつかあります。

もし私があなたなら[theConnection start]、画像がダウンロードされる前にバックグラウンドスレッドがシャットアウトすることを心配する必要がないように、設定されたタイムアウトでリクエストを使用して初期化することを試みます。

例えば:

[request setTimeoutInterval:30];
于 2012-09-04T03:49:02.213 に答える