/ /現在の方法以外でのログ記録に問題がある-iOS、Objective-C

現在のメソッドの外部でログ記録に問題がある - ios 、jective-c

何らかの理由で、ログに記録するときに郵便番号を取得します角かっこ内にあるが、角かっこ外にログインしようとすると(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のおかげでブロックを次のメソッドに渡すことができた後:

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,^{

});

問題を直しました!みんな、ありがとう!

回答:

回答№1は0

括弧内のコード(completionHandlerまたはコールバック)は非同期に実行されます。

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);**
}

回答№2の場合は0

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

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

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

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

それはこうして動いている 完了ハンドラー、および前 self.zip 値があります。


回答№3の場合は0

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

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


回答№4の場合は0

@Andrey、情報をありがとう。私が見つけたこれを共有したかった、誰かが道を進むのを助けるかもしれない。

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.
}];