【问题标题】:Casting down with Objective C使用 Objective C 进行强制转换
【发布时间】:2012-11-12 05:37:39
【问题描述】:

假设我有一个NSManagedObject 的子类,称为MBManagedSquareMBManagedCircle。一个MBManagedSquareMBManagedCircle定义了一个方法prepareFromDictionary:(NSDictionary*)dic,它们的实现是不同的。

假设我有这个代码:

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

因此,Core Data 的实体类型是通过type 字符串动态确定的。所以我只知道这是一个NSManagedObject

我想做的是为正确的类调用prepareFromDictionary: 方法。

所以如果类型是“MBManagedSquare”,我想将对象转换为MBManagedSquare,然后调用

[castedObject prepareFromDictionary:dic];

我尝试做的是:

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

但我得到一个预期的表达式错误。我不确定这是否可能。我该怎么做?

【问题讨论】:

  • 您正在将 iVar 转换为 iVar。这很奇怪。在强制转换中使用大写 Class,并去掉取消引用运算符 (*)。当然重点是没有实际意义的,考虑到所有对象都会响应-class
  • @CodaFi 这也不起作用:Class class = NSClassFromString(type); class *castedObject = (Class)object;

标签: objective-c oop class core-data objc-protocol


【解决方案1】:

如果选择器及其参数匹配,您无需担心调用正确的类——ObjC 有很多动态调度能力。

就实现而言,这两种方法都很常见:

  • 使用您想要的界面创建一个通用基础
  • 或创建两个类都采用的协议:

MONProtocol.h

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

那么(因为您知道它是MBManagedSquareMBManagedCircle 这两种类型之一)要么从基础派生,要么采用协议并声明您的变量,如:

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

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

【讨论】:

  • 但是它怎么知道使用子类技术调用哪个呢?您的示例中的 MBManagedShape 是正确的超类吗?不过,Circle 和 Square 类对 prepareFromDictionary 有不同的实现,因此必须调用正确的方法。
  • 所以实际上使用Core Data,当我用[NSEntityDescription entityForName:@"MBManagedCircle" inManagedObjectContext:_context]; 之类的实体描述初始化一个实体时,返回的对象会自动转换为正确的类型。多么方便!
  • @mohabitar a) 你不需要知道;要使用的实现与您发送消息的实例相匹配。动态调度。 b) 是 c) 每个类都可能以不同的方式实现它。
【解决方案2】:

那里不需要演员表。对象可以是 or 并且函数只存在一次。 检查它是否存在:responsToSelector:@selector(prepareFromDictionary:)

【讨论】:

    猜你喜欢
    • 2014-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-21
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多