【问题标题】:Overloading method names in categories for NSManagedObjects gives a warning in Xcode 4.4 and above在 NSManagedObjects 的类别中重载方法名称会在 Xcode 4.4 及更高版本中发出警告
【发布时间】:2012-07-26 16:39:33
【问题描述】:

我的每个NSManagedObject 子类都有一个类别,工厂方法位于其中,因此在自动重新生成类文件时它们不会丢失。所以我不需要知道我在运行时使用NSManagedObject 的哪个子类,每个子类的工厂方法都具有相同的名称,例如

+ (id)objectWithInfo:(NSDictionary *)info inManagedObjectContext:(NSManagedObjectContext *)context;

(为了清楚起见,在此示例中,假设有一个从 NSManagedObject 派生的实体称为 Item,生成文件 Item.m 和 Item.h,以及我自己的包含文件 Item+Factory.m 和 Item+ 的类别Factory.h,上面的方法所在的位置)。

在 Xcode 4.3 中,这不会产生警告:但 Xcode 4.4(及更高版本将其标记为警告:

(null): 元方法 'objectWithInfo:inManagedObjectContext:' in 来自 ...Item+Factory.o 的类别与来自的相同方法冲突 另一个类别

现在,我很清楚在类别中重载方法的危险,这是一件坏事。然而,我在这里所做的只是将对象视为比它们更通用的类,据我所知,这是明智的。

我做错了吗?或者有没有其他方法来声明我的方法来删除警告?

【问题讨论】:

  • 另外,将类别方法添加到您不拥有的类而不添加前缀(作为命名空间)也是一种不好的形式,因为原始供应商或库供应商可能会添加此方法并导致冲突.
  • 它根据字典中的信息创建一个新对象并返回它。所以对于我拥有的每个 NSManagedObject 子类,这个方法的每个实现都是不同的。你的意思是把这个方法作为猫添加到NSMO,然后在每个子猫中实现?
  • 回复:前缀,是的,我是前缀,但出于隐私考虑已删除。
  • 废话,是否有任何类型的查找或创建逻辑,或者它是一种直接的创建方便方法?

标签: objective-c ios xcode core-data categories


【解决方案1】:

您可能可以将该方法概括为所有对象都以相同的方式工作

+ (id)ps_insertNewObjectForEntityForName:(NSString *)entityName inManagedObjectContext:(NSManagedObjectContext *)context objectInfo:(NSDictionary *)objectInfo;
{
    NSManagedObject *managedObject = [self insertNewObjectForEntityForName:entityName inManagedObjectContext:context];

    [objectInfo enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        [managedObject setValue:obj forKey:key];
    }];

    return managedObject;
}

【讨论】:

    【解决方案2】:

    看起来这是您自己发现的,但为以后的读者澄清一下:

    由于您要向 NSManagedObject 添加所有子类都需要重载的功能,因此最好的方法可能是创建一个 NSManagedObject 的通用子类,然后它可以作为 Item 之类的超类。 (子类化旨在以这种方式工作,但类别不是。)例如:

    // ABCManagedObject.h
    @interface ABCManagedObject : NSManagedObject
    + (id)objectWithInfo:(NSDictionary *)info inManagedObjectContext:(NSManagedObjectContext *)context;
    @end
    
    // ABCManagedObject.m
    @implementation ABCManagedObject
    + (id)objectWithInfo:(NSDictionary *)info inManagedObjectContext:(NSManagedObjectContext *)context
    {
        // no-op; use subclasses instead.
    }
    @end
    
    // Item.h
    @interface Item : ABCManagedObject
    @end
    
    // Item.m
    @implementation Item
    + (id)objectWithInfo:(NSDictionary *)info inManagedObjectContext:(NSManagedObjectContext *)context
    {
        // create and initialize new object and return it
    }
    @end
    

    【讨论】:

    • 谢谢。实际上,我已经这样做了,我只是跳过了那个阶段的解释。我有 MYManagedObject,它有一个工厂类别,我首先在其中声明这些常用方法。然后每个子类都是那个,并且有自己的工厂类别。我认为您的解决方案意味着将方法放在主类中,而不是类别中?但后来我回到自动生成文件的问题......
    • 生成的文件遇到了什么问题?如果只是该方法没有出现在这些文件中,您只需将其添加到 .m 文件中,它将替换超类的实现。您可以开始输入“+ (id)objectWith...”,并且自动完成应该从超类标题中识别它。 (只要确保 .h 文件被 #imported 了。)
    • 我的问题是我希望能够重新自动生成而无需进行任何更改,这就是使用类别的原因。
    【解决方案3】:

    回答我自己的问题:

    我在每个子类的标题中重新声明了该方法。在超类中声明一次对其进行了排序。

    此外,将所有 +Factory.h #imports 移动到预编译的头文件中(并在其他地方删除)大大减少了混乱和额外的警告。

    感谢 Paul.s 让我按照这些思路进行思考。

    【讨论】:

      猜你喜欢
      • 2018-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-03
      • 2014-08-11
      • 1970-01-01
      • 2016-06-10
      • 1970-01-01
      相关资源
      最近更新 更多