Ios 在当前方法之外进行日志记录时遇到问题

Ios 在当前方法之外进行日志记录时遇到问题,ios,objective-c,Ios,Objective C,出于某种原因,当我在括号内登录时会得到一个邮政编码,但当我尝试在括号外登录时会得到一个(null)。我还在头文件中声明了“zip”。我相信这是一个不需要动脑筋的问题。帮点忙 locationManager = [[CLLocationManager alloc] init]; locationManager.distanceFilter = kCLDistanceFilterNone; locationManager.desiredAccuracy = kCLLocati

出于某种原因,当我在括号内登录时会得到一个邮政编码,但当我尝试在括号外登录时会得到一个(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,^{

});

它马上解决了问题!谢谢大家

您在那里使用的完成处理程序是异步的

reverseGocodeLocation:completionHandler:
将在完成计算时调用您定义的块(如果是)

在那之前,那里定义的任何东西都不会运行

发布块后,下一行代码(外部
NSLog
)按常规运行


因此,它在完成处理程序之前运行,并且在self.zip具有值之前运行。

这是因为您在块内获得了zip。它的调用要比后面的代码晚一点。因此,如果您试图访问这些括号之外的zip,您的zip尚未初始化。你需要的是了解积木是如何工作的。以下是一个很好的教程:


还可以查看官方文档

括号内的代码(completionHandler又名回调)将异步执行

您可能希望分为两种不同的方法

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

@安德烈,谢谢你的消息。我想与大家分享我发现的,可能会帮助一些人走上正轨

使用块外部的变量有一个缺点, 但是:默认情况下,它们被视为常量,不能修改 (静态和全局变量是例外)。因此 以下代码生成编译器错误:

通过添加_块存储类型修饰符,我们可以使此代码段正常工作:


好吧,这是有道理的。我如何收集此值以在块外使用它?@JulioLopez-您可以按照正常方式(使用
self.zip
)访问它,但只能在块运行后访问。您可以通过调用块中的委托方法,或将新块发布到GCD来实现这一点。对不起,这对我来说是全新的。您认为您可以向我展示或指出引用的方向吗?我试着使用self.zip,结果仍然是“null”。好吧,我认为应该有某种类型的选择器,在其中的某个地方声明?我在“第二部分”的那句话上一直出错。好吧,我知道我做错了什么。。。我现在明白了;然而,现在我的问题是邮政编码登录到控制台大约50次。有没有办法阻止这种情况发生?这可能是因为您多次调用相同的函数。处理程序应该只调用一次,如果发现多个位置标记,它们将存储在NSArraySo中,那么我认为我需要创建一个完成处理程序?是的,否则您将无法获得位置标记。这种编程风格通常用于长时间运行的任务(网络、存储、获取等)。如果在UI线程上执行,那么繁重的任务不会阻塞UI线程。相反,它将在后台运行,并在完成后执行处理程序。在这种情况下,是否可以使用_块指令(双下划线)帮助?@Smick否,它将尝试不同的方法,但也可以!检查我的编辑!谢谢很高兴我的方法奏效了,你的方法很好。所有的一切都归结于什么对你更有意义。干杯
int matching = 0;
[objects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (/* condition */)
    matching++; // Error since matching is const within the block!
}];
__block int matching = 0;
[objects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (/* condition */)
    matching++; // Can modify matching due to __block modifier.
}];