0

何らかの理由で、括弧内にログインすると郵便番号が取得されますが、括弧外にログインしようとすると (null) が取得されます。また、ヘッダー ファイル内で「zip」を宣言しました。これは簡単なことではないと確信しています。少しの援助?

    locationManager = [[CLLocationManager alloc] init];
    locationManager.distanceFilter = kCLDistanceFilterNone;
    locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
    [locationManager startUpdatingLocation];

    CLGeocoder *fgeo = [[CLGeocoder alloc] init];
    [fgeo reverseGeocodeLocation:locationManager.location completionHandler:^(NSArray     *placemarks, NSError *error) {
        if (!error) {
            CLPlacemark *placemark = [placemarks objectAtIndex:0];
            self.zip = placemark.postalCode;
            **NSLog(@"%@", _zip);**
        }
        }];
    **NSLog(@"%@",self.zip);**

問題解決編集:

SIMON のおかげで、ブロックを次のメソッドに渡すことができたので、OK です。

CLGeocoder *fgeo = [[CLGeocoder alloc] init];
    [fgeo reverseGeocodeLocation:locationManager.location completionHandler:^(NSArray     *placemarks, NSError *error) {
        if (!error) {
            CLPlacemark *placemark = [placemarks objectAtIndex:0];
            self.zip = placemark.postalCode;
            **NSLog(@"%@", _zip);**
[self someMethod];

同じブロックを何度も呼び出すことになることがわかりました。したがって、次のコードを使用して、コードがループしてアプリがクラッシュするのを防ぐことができたので、ブロックを次のようにラップしました。

static dispatch_once_t once;

これで私のコードをラップしました:

dispatch_once(&once,^{

});

それは問題を正しく修正しました!みんな、ありがとう!

4

4 に答える 4

0

@アンドレイ、情報をありがとう。私が見つけたこれを共有したかったのですが、誰かが軌道に乗るのを助けるかもしれません.

http://www.informit.com/blogs/blog.aspx?uk=Ask-Big-Nerd-Ranch-Blocks-in-Objective-C

ただし、ブロック外部の変数を使用する場合の問題点が 1 つあります。デフォルトでは、変数は const と見なされ、変更できません (静的変数とグローバル変数は例外です)。そのため、次のコードはコンパイラ エラーを生成します。

int matching = 0;
[objects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (/* condition */)
    matching++; // Error since matching is const within the block!
}];

__block ストレージ タイプ修飾子を追加することで、このコード スニペットを機能させることができます。

__block int matching = 0;
[objects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (/* condition */)
    matching++; // Can modify matching due to __block modifier.
}];
于 2013-09-15T11:43:39.047 に答える
0

括弧内のコード (completionHandler aka callback) は非同期で実行されます。

2 つの異なる方法に分割することもできます。

- (void)someMethodYouCall {
    locationManager = [[CLLocationManager alloc] init];
    locationManager.distanceFilter = kCLDistanceFilterNone;
    locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
    [locationManager startUpdatingLocation];

    CLGeocoder *fgeo = [[CLGeocoder alloc] init];
    [fgeo reverseGeocodeLocation:locationManager.location completionHandler:^(NSArray     *placemarks, NSError *error) {
    if (!error) {
        CLPlacemark *placemark = [placemarks objectAtIndex:0];
        self.zip = placemark.postalCode;
        **NSLog(@"%@", _zip);**
        [self secondPart];
    }
    }];
}

-(void) secondPart {
    **NSLog(@"%@",self.zip);**
}
于 2013-09-15T09:58:47.390 に答える
0

そこで使用している完了ハンドラーは非同期です。

reverseGocodeLocation:completionHandler:は、計算が完了したときに、定義したブロックを呼び出します (いつでも)。

それまでは、そこで定義されたものは何も実行されません。

ブロックが投稿された後、コードの次の行 (外側NSLog) が通常どおり実行されます。

したがって、完了ハンドラーのself.zipに実行され、前に値があります。

于 2013-09-15T09:42:27.103 に答える
0

これは、ブロック内で zip を取得するためです。直後のコードよりも少し遅れて呼び出されます。したがって、これらのブラケットの外側にある zip にアクセスしようとすると、zip はまだ初期化されていません。必要なのは、ブロックがどのように機能するかを理解することです。開始するのに適したチュートリアルは次のとおりです。ブロックのチュートリアル

公式ドキュメントもご覧くださいApple公式ドキュメント

于 2013-09-15T09:42:38.267 に答える