2

FlickrAPIの写真の応答を解析するクラスFlickrImageのインスタンスを作成しています。このクラスには、ジオロケーションを取得するために別のAPI呼び出しを行うgetLocationメソッドがあります。

NSLog(@"getting location for %i",self.ID);
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
OFFlickrAPIRequest *flickrAPIRequest = [[OFFlickrAPIRequest alloc] initWithAPIContext[appDelegate sharedDelegate].flickrAPIContext];
[flickrAPIRequest setDelegate:self];

NSString *flickrAPIMethodToCall = @"flickr.photos.geo.getLocation";
NSDictionary *requestArguments = [[NSDictionary alloc] initWithObjectsAndKeys:FLICKR_API_KEY,@"api_key",self.ID,@"photo_id",nil];

[flickrAPIRequest callAPIMethodWithGET:flickrAPIMethodToCall arguments:requestArguments];
[pool release];

APIからの応答をキャッチし、ジオロケーションデータでFlickrImageインスタンスを更新するコールバックメソッドを実装しましたが、呼び出されることはありません。インスタンスが作成される場所は次のとおりです。

NSDictionary *photosDictionary = [inResponseDictionary valueForKeyPath:@"photos.photo"];
NSDictionary *photoDictionary;
FlickrImage *flickrImage;
for (photoDictionary in photosDictionary) {
    flickrImage = [[FlickrImage alloc] init];
    flickrImage.thumbnailURL = [[appDelegate sharedDelegate].flickrAPIContext photoSourceURLFromDictionary:photoDictionary size:OFFlickrThumbnailSize];
    flickrImage.hasLocation = TRUE; // TODO this is actually to be determined...
    flickrImage.ID = [NSString stringWithFormat:@"%@",[photoDictionary valueForKeyPath:@"id"]];
    flickrImage.owner = [photoDictionary valueForKeyPath:@"owner"];
    flickrImage.title = [photoDictionary valueForKeyPath:@"title"];
    [self.flickrImages addObject:[flickrImage retain]];
    [flickrImage release];
    [photoDictionary release];
}

これを解決するのに役立つかもしれないと思ったのretainですが、そうではありません-そして、NSMutableArray(flickrImagesはNSMutableArray)はとにかくそのメンバーを保持しませんか?

編集メソッド(最初のコードスニペット)がスレッドで起動されることを追加する必要がgetLocationあります:[NSThread detachNewThreadSelector:@selector(getLocation)toTarget:self withObject:nil];

4

6 に答える 6

2

リクエストが行われないため、デリゲートメソッドが呼び出されることはありません。を呼び出すとcallAPIMethodWithGET:、現在のスレッドの実行ループで非同期に実行されるように通信が設定され、すぐに戻ります。そうすれば、ブロックせずにメインスレッドで安全に呼び出すことができます。

自分で作成したスレッドからメソッドを呼び出しているため、メインの実行ループは表示されませんが、新しいスレッドの実行ループは表示されます。ただし、実行ループを実行することはないため、メッセージが送信されることも、応答が受信されることも、デリゲートが呼び出されることもありません。

新しいスレッドを呼び出すことでこれを修正できます。[[NSRunLoop currentRunLoop] run]それは仕事を起こさせるでしょう。ただし、この場合、最初から新しいスレッドを切り離さない方が簡単です。プログラムがブロックされることはなく、デリゲートメソッドが再入可能である必要があることを心配する必要はありません。

于 2009-12-11T20:38:38.780 に答える
1

別のスレッドでXMLを要求して解析するときにも、この問題が発生しました。私の解決策は、次のことです。

while([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:start] && !isFinished){

}

start = [NSDate dateWithTimeIntervalSinceNow:3];これは基本的にタイムアウトであり、永久に存続することはなく、isFinished解析が完了するとtrueに設定されます。

于 2009-12-10T17:11:36.947 に答える
0

さて、上記の提案のいくつかの助けを借りて、私はそれを解決しました。

  • retain実際にメモリリークが発生したため、余分なものを削除しました。それは最初から正しく見えなかったので、それについての私の腸の感覚は何かの価値があります、それは良いことです;)
  • API呼び出しはすでに非同期であり、非ブロッキングであるために追加のスレッドを必要としないため、冗長なスレッドを削除しました。その後、コールバックメソッドが呼び出されていましたが、オブジェクトの保持に関してさまざまな問題が発生しました。興味があれば、その質問もチェックしてみてください。

皆さんありがとう。

于 2009-12-12T11:08:48.453 に答える
0

私はこれらのフリッカーAPIラッパーに精通していませんが、このコードでは次のようになっています。

NSDictionary *requestArguments = [[NSDictionary alloc] initWithObjectsAndKeys:FLICKR_API_KEY,@"api_key",self.ID,@"photo_id",nil];

FLICKR_API_KEYとself.IDの両方がnilではないことを確認しますか?どちらかがnilの場合、意図したよりもアイテムが少ない辞書になります。

于 2009-12-09T02:49:54.413 に答える
0

実装したコールバックメソッドを投稿していただけOFFlickrAPIRequestませんか。デリゲートが必要なコールバックを実装しないと何も起こらないように見えるため、これは単純なタイプミスにすぎない可能性があります。

flickrAPIRequest:didFailWithError:API呼び出しからエラーが返されたかどうかを確認するためにも実装しましたか?

于 2009-12-11T14:36:41.320 に答える
-1

OFFlickrAPIRequestのsetDelegateメソッドは、デリゲートを本来のように保持しません。これは、リクエストが存在する限り(またはクラスにパッチを適用して独自の参照を適切に所有する)、デリゲートが存続していることを確認するために立ち往生していることを意味します。

于 2009-12-09T17:16:14.430 に答える