0

過去 2 時間、CLGeocoder場所のリバース ジオコーディングに使用されるクラス メソッドの実装に苦労していました。

クラス参照Xcodeの下のドキュメントでこのメソッドに提供されているコードは次のとおりです。CLGeocode

- (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler

私は自分のコードでそれを使用しようとしていましたが、運がありませんでした。だから私はいくつかの古いスタックオーバーフローの質問を見て、最終的に私のために働く実装を見つけました.

これは私のために働くコードです:

-(IBAction)gpsButton {

 CLGeocoder *geocoder = [[CLGeocoder alloc]init];

 [geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error){

  CLPlacemark *placemark = placemarks[0];
  NSLog(@"Found %@", placemark.thoroughfare);

}

 ];

}

私が理解していないのは、最終的なコードが実際にどのように見える必要があるかではないのに、xcode のドキュメントに (CLLocation *) と (CLGeocodeCompletionHandler) が含まれている理由です。

「場所」オブジェクトは CLLocation クラスのインスタンスである必要があり、「completionHandler」オブジェクトは CLGeocodeCompletionHandler クラスのインスタンスである必要があることを思い出させようとしているだけですか?

このメソッドを実装する前に、メソッドが適切に機能するように、CLLocationクラスとクラスのオブジェクトを作成して初期化する必要があることを思い出させようとしていますか? CLGeocodeCompletionHandlerこの場合、なぜCLLocationxcode の例にポインタがあるのにCLGeocodeCompletionHandlerないのでしょうか?

これが「基本」タイプの質問であることは理解していますが、参考文献をいくつか調べましたが、それらが物事を説明している方法は、この現在の混乱を本当に助けてくれません.

お手伝いありがとう。

4

2 に答える 2

1

あなたは言う:

私が理解していないのは、最終的なコードが実際にどのように見える必要があるかではないのに、xcode のドキュメントに (CLLocation *) と (CLGeocodeCompletionHandler) が含まれている理由です。

問題は、これ最終的なコードの外観です。したがって、ご指摘のとおり、reverseGeocodeLocation:completionHandler:メソッドは次のように定義されています。

- (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;

さらに、 の定義を見ると、次のように、目印の配列とオブジェクトの 2 つのパラメーターCLGeocodeCompletionHandlerを返し、受け取るブロックとして定義されています。voidNSError

typedef void (^CLGeocodeCompletionHandler)(NSArray *placemarks, NSError *error);

したがって、以下のコード サンプルは、この定義に正確に準拠しています。

[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error){

    CLPlacemark *placemark = placemarks[0];
    NSLog(@"Found %@", placemark.thoroughfare);

}];

のメソッド定義が実際の複雑なブロック定義ではなく typedefreverseGeocodeLocation:completionHandler:を使用している理由を尋ねている場合、コードを単純化するために使用しています。CLGeocodeCompletionHandlerはい、Xcode の「コード補完」は少し役に立たなくなりますが、ブロック パラメーターを使用してこのメ​​ソッドを実装するコードを実際に書いているときは、作業がずっと楽になります。

typedefブロック パラメーターを受け取り、これらのブロックをプロパティに格納するクラスを持つ独自のメソッドを書き始めると、非常に厄介なブロック構文のタイプミスに起因する多くの単純なエラーを排除して、使用が本当に天の恵みであることがわかります。

たとえば、そのブロックを変数に保持し、その変数を の呼び出しで使用したいとしますreverseGeocodeLocation。typedef があるため、それは非常に簡単です。

CLGeocodeCompletionHandler customHandler = ^(NSArray *placemarks, NSError *error){
    CLPlacemark *placemark = placemarks[0];
    NSLog(@"Found %@", placemark.thoroughfare);
};

[geocoder reverseGeocodeLocation:currentLocation completionHandler:customHandler];

typedef がなければ、もう少し扱いに​​くい構文に頼る必要があります。

void (^customHandler)(NSArray *, NSError *) = ^void(NSArray *placemarks, NSError *error) {
    CLPlacemark *placemark = placemarks[0];
    NSLog(@"Found %@", placemark.thoroughfare);
};

[geocoder reverseGeocodeLocation:currentLocation completionHandler:customHandler];

確かに、これはいくらか不自然な例ですが、ブロックを使用するにつれて、typedefコード全体で同じブロック シグネチャを何度も使用する必要がある場合に、 が提供する単純さを理解するようになります。

そのため、カスタム ブロックをパラメーターとして持つメソッドが表示されるたびに、typedefもう 1 レベル詳細にドリルダウンして、それを確認するとtypedef、すべてが明確になります。

于 2013-12-24T04:35:11.417 に答える
0

初期化とreverseGeocodeCLLocationが必要なクラスですがCLGeocodeCompletionHandler、ブロックtypedefハンドルのコールバックです。したがって、初期化する必要はありません。

于 2013-12-24T03:01:24.910 に答える