[英]IOS: identify a generic object
In my app I should analyze an object and I do this: 在我的应用程序中,我应该分析一个对象,我这样做:
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;
}
in this way I should verify if my object belong to a class to obtain its property, but is there a faster way to obtain the property "name" from my objects? 通过这种方式,我应该验证我的对象是否属于一个类以获取其属性,但是有更快的方法从我的对象获取属性“name”吗? All objects have "name" property.
所有对象都具有“name”属性。
thanks 谢谢
The code aforementioned have a common issue: whenever the name property is missing it dumps core. 上述代码有一个共同的问题:每当缺少name属性时,它都会转储核心。 Here is my version that is a hell lot safer, and a one-liner:
这是我的版本更安全,一个单行:
id name = ([object respondsToSelector:@selector(name)]) ? [object name] : nil;
Hope the ternary operator did not confise you. 希望三元运营商不要让你担心。 The nil can be replaced with whatever is appropriate if a name is not present, like:
如果名称不存在,则可以用适当的替换nil,例如:
static NSDictionary *defaultNameForClasses = @{@"FooClass": @"Foo", /* ... */};
// ...
id name = ([object respondsToSelector:@selector(name)]) ? [object name] : defaultNameForClasses[NSStringFromClass([object class])];
Take a look at Objective-C protocols at apple developer docs. 在Apple开发人员文档中查看Objective-C协议。
Long story short: You can define all the properties you need in a protocol, make your classes (Person, Animal etc) follow it and then use [object_selected conformsToProtocol:MyProtocol]
to safely get the property like this: 简而言之:您可以在协议中定义所需的所有属性,使您的类(Person,Animal等)遵循它,然后使用
[object_selected conformsToProtocol:MyProtocol]
安全地获取如下属性:
if ([object_selected conformsToProtocol:MyNamingProtocol]) {
id<MyNamingProtocol> namedObject = object_selected;
NSString *name = [namedObject name];
}
Make a protocol in a separate .h file. 在单独的.h文件中创建协议。 The code would look similar to the following:
代码看起来类似于以下内容:
@protocol NamedObjectProtocol
@protocol NamedObjectProtocol
@property (nonatomic, strong) NSString *name;
@property(nonatomic,strong)NSString * name;
@end
@结束
Then, make both object classes declare conformance to this protocol. 然后,使两个对象类声明符合此协议。 Then, you can cut the if/else spaghetti and get the property like this, irrespective of whether
anObject
is an instance of a Person
or Animal
class. 然后,无论
anObject
是Person
还是Animal
类的实例,都可以剪切if / else spaghetti并获得这样的属性。
id <NamedObjectProtocol> namedObject = anObject;
NSString *name = namedObject.name;
You should also consider making the Animal
and Person
classes inherit from a superclass, which has all commonalities, such as the name property. 您还应该考虑使
Animal
和Person
类继承自超类,该超类具有所有共性,例如name属性。 This would allow you to write code like: 这将允许您编写如下代码:
Character *character = anObject;
NSString *name = character.name;
You may use Key-value coding to safely access the property. 您可以使用键值编码来安全地访问该属性。 Just use:
只需使用:
NSString* name = [object_selected valueForKey:@"nome"]
The advantage of this is that application won't crash if object_selected
doesn't have a property called name
, in this case the value of name
variable will be nil
. 这样做的好处是,如果
object_selected
没有名为name
的属性,应用程序不会崩溃,在这种情况下, name
变量的值将为nil
。
Another way to avoid crash is to check if object responds to selector, like this 另一种避免崩溃的方法是检查对象是否响应选择器,就像这样
if ([object_selected respondsToSelector:@selector(name)]) {
//...
}
您可以只调用[object_selected name]
,但是您可能会收到name may not be a property
(或类似name may not be a property
编译器警告。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.