IOS:标识一个通用对象



在我的应用程序中,我应该分析一个对象,我这样做:

 if ([object_selected isKindOfClass:[Person class]]) {
    Persone *obj = (Persone*)object_selected;
    NSString *name = obj.nome;
    NSString *surname = obj.surname;
}
else if ([object_selected isKindOfClass:[Animal class]]) {
        Animal *obj = (Animal*)object_selected;
        NSString *name = obj.nome;
        NSString *breed = obj.breed;
    }

以这种方式,我应该验证我的对象是否属于一个类来获取其属性,但是是否有一种更快的方法来从我的对象中获取属性"name"?所有对象都有"name"属性。

谢谢

前面提到的代码有一个共同的问题:只要缺少name属性,它就会转储核心。下面是我的版本,它要安全得多,而且只有一行字:

id name = ([object respondsToSelector:@selector(name)]) ? [object name] : nil;

希望三元运算符没有让您出错。如果没有名称,则可以用任何合适的内容替换nil,例如:

static NSDictionary *defaultNameForClasses = @{@"FooClass": @"Foo", /* ... */};
// ...
id name = ([object respondsToSelector:@selector(name)]) ? [object name] : defaultNameForClasses[NSStringFromClass([object class])];

查看苹果开发者文档中的Objective-C协议。

长话短说:你可以在协议中定义所有你需要的属性,让你的类(Person, Animal等)遵循它,然后使用[object_selected conformsToProtocol:MyProtocol]安全地获得属性,像这样:

if ([object_selected conformsToProtocol:MyNamingProtocol]) {
  id<MyNamingProtocol> namedObject = object_selected;
  NSString *name = [namedObject name];
}

在单独的.h文件中创建一个协议。代码类似于下面的代码:

@protocol NamedObjectProtocol

@property (nonatomic, strong) NSString *name;

@end

然后,使两个对象类声明符合该协议。然后,无论anObjectPerson类的实例还是Animal类的实例,您都可以切断if/else面条并获得像这样的属性。

id <NamedObjectProtocol> namedObject = anObject;
NSString *name = namedObject.name;

你还应该考虑让AnimalPerson类继承自一个超类,它具有所有的共性,比如name属性。这将允许您编写如下代码:

Character *character = anObject;
NSString *name = character.name;

您可以使用键值编码来安全地访问该属性。只使用:

NSString* name = [object_selected valueForKey:@"nome"]

这样做的好处是,如果object_selected没有名为name的属性,则应用程序不会崩溃,在这种情况下,name变量的值将为nil

另一种避免崩溃的方法是检查对象是否响应选择器,就像这样
if ([object_selected respondsToSelector:@selector(name)]) {
//...
}

您可以直接调用[object_selected name],尽管您可能会得到name may not be a property(或类似)的编译器警告。

最新更新