Objectiv-C: Get an objects class and cast the object to it dynamically

Let's say I have a collection of objects of different types/classes, i.e. an NSArray.

I know that all of this objects inherit from NSManagedObject and all of them have a property named "uuid"

Now, I want to loop over this array, retrieve each objects uuid and add it to another array, like this:

NSMutableArray *objectUUIDs = [[NSMutableArray alloc] initWithCapacity:0];
for (NSObject *object in objects) {
    // somehow cast the object to its class, so that i can send get its uuid
}

Actually, I could check for the class by [object class] in an if-else-clause, and cast it respectively, but as i have 30 something classes, I would like to do something more generic, like (in pseudo code):

// give me the object's true class instead of NSManagedObject
// add the object uuid to my objectUUIDs array

Answers


As you say all objects are NSManagedObjects and all have a property uuid, you can use Key-Value-Coding

NSMutableArray *objectUUIDs = [@[] mutableCopy];
for (NSManagedObject *object in objects) {
    [objectUUIDs addObject: [object valueForKey:@"uuid"]];
}

or

NSArray *objectUUIDs = [objects valueForKey:@"uuid"]; 

NSArray's -valueForKey doc


if you enumerate over an collection of objects of different classes you shouldn't type the enumerated object NSObject, but use either the closest common super class, or id — the generic objective-C object type. The reason is that you can send any message to an object typed with id, and you can do further testing. With other more concrete classes you must ensure a message is under stud by an given method.


You state

// give me the object's true class instead of NSManagedObject

The object doesn't change during casting. if you put a instance of MyFabulousManagedObject (subclass of NSManagedObject) in an array, and later you cast it to NSManagedObject, it is actually still an instance of MyFabulousManagedObject


While vikingoseguindo's solution is probably best, there's also this possibility:

Define a protocol which has this property (or anything you know for sure is shared among all the objects):

@protocol FooBarProtocol
@property NSUUID *uuid;
@end

Now iterate over the original array as such:

NSMutableArray *objectUUIDs = [NSMutableArray array];
for (id<FooBarProtocol> object in objects) {
    [objectUUIDs addObject:object.uuid];   
}

Here, we're simply casting the objects all to objects that conform to FooBarProtocol, although it may be true that all of your objects already conform to a protocol that defines this property, or perhaps all have a common superclass with this property defined.

The main point here is that you just need to cast them to anything that defines the property.


Note that as written, this will crash if the object actually doesn't have a uuid property. Might be a good idea to add:

if ([object respondsToSelector:@selector(uuid)]) {
    [objectUUIDs addObject:object.uuid];
}

And this also avoids having a massive chain of if statements to check all the different classes. We don't care what sort of class it is. We only care that it can give us a UUID.


Need Your Help

install SSL Cert in client machine programmatically using C#

c# wcf

I've developed a Desktop application using c# which consume WCF on remote server over the internet i need to secure the communication between WCF Server and the Desktop Application (client) using S...

Problems with Polynomial.java zeros method

java polynomial-math

Here is the location of the source code (using Dropbox).