简体   繁体   中英

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? All objects have "name" property.

thanks

The code aforementioned have a common issue: whenever the name property is missing it dumps core. 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:

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.

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:

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

Make a protocol in a separate .h file. The code would look similar to the following:

@protocol NamedObjectProtocol

@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.

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. 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 .

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编译器警告。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM