何らかの理由で、ログに記録するときに郵便番号を取得します角かっこ内にあるが、角かっこ外にログインしようとすると(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.
}];