如果对象为空,则执行某些操作

Posted

技术标签:

【中文标题】如果对象为空,则执行某些操作【英文标题】:Do something if an object is null 【发布时间】:2013-11-06 15:34:07 【问题描述】:

我有一个使用 GPS 并在某些标签上显示实际位置的应用程序。这里是更新位置的方法:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation

    NSLog(@"didUpdateToLocation: %@", newLocation);
    CLLocation *currentLocation = newLocation;

    if (currentLocation != nil) 
        longitude.text = [NSString stringWithFormat:@"%.3f", currentLocation.coordinate.longitude];
        latitude.text = [NSString stringWithFormat:@"%.3f", currentLocation.coordinate.latitude];
    

    NSLog(@"Resolving the Address");
    [geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) 
        NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
        if (error == nil && [placemarks count] > 0) 
            placemark = [placemarks lastObject];
            [address sizeToFit];
            NSArray *locationArray = [[NSArray alloc] initWithObjects:placemark.thoroughfare,placemark.subThoroughfare,
                                      placemark.postalCode,placemark.locality,placemark.country, nil];
            address.text = [NSString stringWithFormat:@"%@, %@\n%@ %@\n%@",
                                 [locationArray objectAtIndex:0],
                                 [locationArray objectAtIndex:1],
                                 [locationArray objectAtIndex:2],
                                 [locationArray objectAtIndex:3],
                                 [locationArray objectAtIndex:4]];
         else 
            NSLog(@"%@", error.debugDescription);
        
     ];


现在,有时 'locationArray' 的某些对象是 'null',而相关标签在应用程序上显示为 '(null)',这不太好。所以我需要一个'if'循环来检查'locationArray'的对象是否为'null',如果是,则不会显示。有什么想法吗?

更新

我解决了删除数组并使用@***foe 的方法(稍作修改)的问题。代码如下:

- (NSString *)sanitizedDescription:(NSString *)obj 
    if (obj == nil)
    
        return @"";
    
    return obj;


- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation

    //NSLog(@"didUpdateToLocation: %@", newLocation);
    CLLocation *currentLocation = newLocation;

    if (currentLocation != nil) 
        longitude.text = [NSString stringWithFormat:@"%.3f", currentLocation.coordinate.longitude];
        latitude.text = [NSString stringWithFormat:@"%.3f", currentLocation.coordinate.latitude];
    

    NSLog(@"Resolving the Address");
    [geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) 
        //NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
        if (error == nil && [placemarks count] > 0) 
            placemark = [placemarks lastObject];
            [address sizeToFit];

            address.text = [NSString stringWithFormat:@"%@, %@\n%@ %@\n%@",
                            [self sanitizedDescription:placemark.thoroughfare],
                            [self sanitizedDescription:placemark.subThoroughfare],
                            [self sanitizedDescription:placemark.postalCode],
                            [self sanitizedDescription:placemark.locality],
                            [self sanitizedDescription:placemark.country]];
         else 
            NSLog(@"%@", error.debugDescription);
        
     ];


非常感谢大家的帮助:)

【问题讨论】:

为什么要创建数组? 因为我试图在数组上找到解决方案,但我可以毫无问题地更改代码.. NSArray(及其子类)不能(除非对 API 进行一些低级滥用)包含 nil(Objective-C 表示 null),所以还有别的必须在这里进行。您是否尝试过使用调试器单步调试代码? 目前还不清楚为什么要将地标字符串放入数组中。如果您只想显示格式正确的地标地址,请参阅***.com/questions/7848291/…。 【参考方案1】:

您必须创建一个辅助方法,用于测试 NSNull 类并做一些不同的事情:

- (NSString *)sanitizedDescription:(id)obj 
    if ([obj isKindOfClass:[NSNull class]]) 
        return @"";
    
    return [obj description];

然后直接调用它而不是description

address.text = [NSString stringWithFormat:@"%@, %@\n%@ %@\n%@",
                   [self sanitizedDescription:[locationArray objectAtIndex:0]],
                   [self sanitizedDescription:[locationArray objectAtIndex:1]],
                   [self sanitizedDescription:[locationArray objectAtIndex:2]],
                   [self sanitizedDescription:[locationArray objectAtIndex:3]],
                   [self sanitizedDescription:[locationArray objectAtIndex:4]]];

注意:此方法不必在self 中,也不必是实例方法,它可以作为类方法正常工作。或许创建一个包含有用类方法的辅助类?

【讨论】:

很好,但现在问题是数组中的空对象导致 XCode,如果“locationArray”的对象为空,则停止并出现错误:由于未捕获的异常“NSRangeException”而终止应用程序,原因: '*** -[__NSArrayI objectAtIndex:]: 索引 1 超出范围 [0 .. 0]' @DrKey 是的,您不能将nuls 放入Objective-C 集合类中。您必须检查 nul 并插入 [NSNull null] NSNull 是一个单身人士。您可以使用 obj == [NSNull null] 进行更快的比较【参考方案2】:

查看您的代码,您使用的是NSArray,并且您声称它持有 NULL 这是错误的。 NSArray 不能保存 NULL 指针。这里肯定有其他问题。

如果你真的想在 Objective-c 中的数组中存储 NULL 值,你要么需要使用直接的 C 数组,要么使用 NSPointerArray。否则,您需要使用 [NSNull null] 来表示 NSArray 中的 NULL 值(正如其他人指出的那样)。

选择最适合您的需求和设计的方法。请注意 NSPointerArray 在 ios 6.0 或更高版本中更容易使用(您标记为 iOS 7 所以应该没问题)。根据您的需要,指针数组可以与强或弱 ARC 语义一起使用。

【讨论】:

以上是关于如果对象为空,则执行某些操作的主要内容,如果未能解决你的问题,请参考以下文章

Mapstruct 映射:如果所有源参数属性为空,则返回空对象

js过滤数组中都为空的对象几种方式

Kotlin学习快速入门——空安全

如果一个属性可以为空,则比较对象时 FluentAssertions 失败

访问有时为空对象的属性而不会出错[重复]

约束索引三范式