Вопрос

Say I have a subclass of NSManagedObject called MBManagedSquare and MBManagedCircle. An MBManagedSquare and MBManagedCircle define a method prepareFromDictionary:(NSDictionary*)dic, and both of their implementations are different.

Say I have this code:

NSString *type = // could be @"MBManagedSquare" or @"MBManagedCircle"
NSEntityDescription *desc = [NSEntityDescription entityForName:type inManagedObjectContext:_context];
NSManagedObject *object = [[NSManagedObject alloc] initWithEntity:desc insertIntoManagedObjectContext:_context];

So the type of entity it will be with Core Data is determined dynamically via a type string. So all I know is that it is an NSManagedObject.

What I want to do is call the prepareFromDictionary: method for the right class.

So if the type is "MBManagedSquare", I want to cast the object to an MBManagedSquare, and then call

[castedObject prepareFromDictionary:dic];

What I tried doing is:

Class class = NSClassFromString(type);
class *castedObject = (class*)object;

but I get an expected expression error. I'm not sure if this is even possible. How would I do this?

Это было полезно?

Решение

You don't need to worry about calling the right class if the selectors and their parameters match -- ObjC has plenty of dynamic dispatch powers.

As far as an implementation, it's pretty common to either:

  • create a common base with the interface you want
  • or create a protocol which both classes adopt:

MONProtocol.h

@protocol MONManagedShapeProtocol < NSObject >
- (void)prepareFromDictionary:(NSDictionary *)pDictionary;
@end

then (since you know it is one of the two types, MBManagedSquare or MBManagedCircle) either derive from the base or adopt the protocol and declare your variable like:

// if subclass
MBManagedShape * castedObject = (MBManagedShape*)object;

or

// if protocol
NSManagedObject<MONManagedShapeProtocol>* castedObject =
                        (NSManagedObject <MONManagedShapeProtocol>*)object;

Другие советы

no need for a cast there. the object can be either or and the function is only there once. checking if it is there is good: respondsToSelecctor:@selector(prepareFromDictionary:)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top