2013-12-09 3 views
2

В Objective C у меня есть объект, например. Person с большим количеством полей firstName, lastName, phoneNumber, address, city ... и так далее. Эти типы полей: NSString, и любой из них может быть nil.Просмотр полей объекта

Теперь я хочу, чтобы объединить свои значения поля в другом NSString:

Person *p = ... 
NSMutableString *s = [[NSMutableString alloc] init]; 
for (NSString *field in @[p.firstName, p.lastName, p.phoneNumber, 
          p.adress, p.city, ....more fields...]) { 
    if ([field length] > 0) { 
     [s appendFormat:@"%@\n", field]; 
    } 
} 

Проблема в том, что этот код аварии всякий раз, когда один из поля nil. У меня есть исключение:

[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object 
from objects[0]' 

Как я мог справиться просто случай nil значений в пределах моего for цикла?

+0

редактировал свой вопрос для ясности: будет много полей в объекте (около 15) –

+0

Хорошо, это означает, что я должен изменить свой ответ :) –

+0

@ Том Йеп, извините, мой пример был слишком конкретным. –

ответ

3

Я согласен с сообщением @ TomPace, для этого небольшого числа я бы сделал простой if/else.

Однако, возможно, вам понадобятся петли через список полей.

Плохая идея, чтобы слепо вытащить значения в массив, как вы могли бы попытаться вставить значения nil в массив. В этом случае было бы лучше помещать имена полей в массив ключей в виде строк и циклически перебирать список, используя valueForKey: для доступа к значениям. Я бы, возможно, сохранил список keys где-то еще, где он может быть использован снова.

Person *p = ... 
NSMutableString *s = [[NSMutableString alloc] init]; 

NSArray *keys = @[@"firstName", @"lastName", @"phoneNumber", @"adress", @"city"]; 

for (NSString *key in keys) 
{ 
    NSString *value = [p valueForKey:key]; 
    if ([value length] > 0) { 
     [s appendFormat:@"%@\n", value]; 
    } 
} 
0

Для выбора полей это малое, не используйте цикл for.

Возможно, вы сохраняете немного кода, создавая структуру for-loop, но это действительно не так, если вы создаете NSArray только с несколькими полями, и особенно потому, что вы не можете поставить ноль в нем.

Лучший способ пойти:

Person *p = ... 
NSMutableString *s = [[NSMutableString alloc] init]; 
if ([p.firstName length] > 0) [s appendFormat:@"%@\n", p.firstName]; 
if ([p.lastName length] > 0) [s appendFormat:@"%@\n", p.lastName]; 
if ([p.phoneNumber length] > 0) [s appendFormat:@"%@\n", p.phoneNumber]; 
if ([p.adress length] > 0)  [s appendFormat:@"%@\n", p.adress]; 
if ([p.city length] > 0)  [s appendFormat:@"%@\n", p.city]; 

Edit, после того, как оригинальный вопрос был обновлен с большим количеством полей. Как и @BergQuester, подход к поддержке большего произвольного набора полей использует проверку типа KVO.

NSArray *fieldNames = @[@"firstName", @"lastName", @"phoneNumber", ....more fields...]; 
NSString *field; 
for (NSString *fieldName in fieldNames) { 
    field = [p valueForKey:fieldName]; 
    if ([field length] > 0) { 
     [s appendFormat: @"%@\n", field]; 
    } 
} 
+0

'> 0' является избыточным (не так, просто указывая еще один стилистический вариант.) –

+0

@AaronBrager благодарит, да, вы правы. Наверное, я просто следовал стилю оригинального вопроса. Я предпочитаю упущение. –

0
Person *person = [[Person alloc] init]; 
person.firstName = nil; 
person.lastName = @"lastName"; 

NSMutableString *s = [[NSMutableString alloc] init]; 
[s appendFormat:@"%@\n", person.firstName == [email protected]"":person.firstName]; 
[s appendFormat:@"%@\n", person.lastName == [email protected]"":person.lastName]; 
0

Вы можете переопределить методы получения класса Person.

@implementation Person 

    - (NSString *)firstName{ 
     if (_firseName == nil) 
      _firstName = @""; 
     return _firstName; 
    } 
///....Other setters  

    @end 

Нравится программа? Поделись с друзьями!

+0

Это геттеры, а не сеттеры. –

+0

Кроме того, это решение отнимает память и может иметь отрицательные побочные эффекты. –

0

Попробуйте создать NSMutableString категорию

#import "NSMutableString+checkForNilObject.h" 

@implementation NSMutableString (checkForNilObject) 


-(void) appendNotNillObject:(NSString *) string 
{ 
    if(string) 
    { 
     [self appendString:string]; 
    } 
} 
@end 
+0

'string &&' бессмысленно. –

+0

@AaronBarger, Да, вы правы. –