Core Data: Detecting the type and casting it
I have set up a Core Data model that includes an entity, Item
with a 1->M r开发者_运维知识库elationship with the abstract entity Place
, so that an item has many places. There are several entities with the parent set to Place
.
I want to set up several UI elements depending on the descendent place types. I have a loop that looks something like this:
for (Place *place in item.places) {
}
... but I'm not sure how to detect what type the place is, and how to cast it to the proper type so that I can access its properties.
Thanks for any help!
Not entirely sure what you are asking, but sounds like you have a collection of objects which are of subclasses of Place, and you need to detect the concrete type at runtime.
Here's how you do the branching and casting:
for (id object in item.places) {
if ([object isKindOfClass:[SomeConcretePlace class]]) {
((SomeConcretePlace *)object).someProperty = something;
} else if ([object isKindOfClass:[AnotherConcretePlace class]]) {
somethingElse = ((AnotherConcretePlace *)object).someProperty;
}
}
Be sure to look at docs for isKindOfClass: and isMemberOfClass: in NSObject reference to understand the difference, you can use either depending on the circumstances.
(You can substitute "id object" with "Place *object", I was just using id in my code. -- edit: or maybe you can't if it's abstract, see mzarra's comment. "id" works fine.)
You can determine what place is with one of several options:
- You can call
[[object entity] name]
to determine the name of the child - If you have subclasses NSManagedObject for these children then you can test against its class using
[object isKindOfClass:[XXXX class]]
Since abstract entities can never be instantiated you are best off referencing the results of your query as id
or NSManagedObject
and then determining which child you are dealing with from there. That way, conceptually, you never get confused as to what you can and cannot instantiate.
Also as an update to this, you do not need to cast the object if you reference it as an id
. id
is useful as a wildcard in these situations and will be trusted/assumed to accept any message (method call) of any class that the calling class is aware of (i.e. that has been previously imported into the class. This is extremely useful in cases like this where you are dealing with multiple child objects.
精彩评论