如何在对类进行子类化时避免编译警告?

时间:2012-03-10 01:10:34

标签: iphone objective-c ios

假设我们有父类

ParentViewController.h

@interface ParentViewController

....

@end

ParentViewController.m

@interface ParentViewController()

- (NSArray *)selectedItems;

@end

@implementation ParentViewController

.....

@end

然后我们将其子类化

ChildViewController.h

@interface ChildViewController : ParentViewController

....

@end

ChildClassViewController.m

@implementation ChildViewController

- (void)doSomething
{
    // XCode Warning Flag on this line
    NSUInteger count = [self selectedItems];

    .....
}

XCode会在注释行设置警告标志,并说“找不到实例方法'-selectedItems'(返回类型默认为'id')。

是的我知道在ObjC中没有私有方法这样的东西,但是使用空类别的方法可以做到这一点。但不知怎的,它不会被子类继承。

我通常通过将方法从ParentViewController.m移动到ParentViewController.h来修复它。这感觉很奇怪,我放弃了将方法设为私有的能力,因为我需要将其子类化。

现在我的问题是:

  1. 为什么父子类无法找到在.m文件的类别中声明的那些方法?

  2. 有没有办法删除警告标记,但不会失去保持方法私密的功能。

  3. 希望有更多经验的人能够帮助解释这个恼人的问题。

2 个答案:

答案 0 :(得分:3)

首先,请注意您的“空类别”根本不是类别,它是类扩展。类扩展与类别非常相似,但它们在Objective C 2.0中是新的,它们的使用略有不同。主要是,如果您没有在类扩展中实现方法,编译器将警告您,但它不会与类别。无论如何,关于手头的问题......

Objective-C中的隐私是关于可见性的。如果编译器看不到正在使用的方法的声明,您将收到警告。请注意,如果要在与类扩展相同的文件中实现子类,编译器将不会发出警告,因为它可以看到声明。

因此,如果要在子类中使用“私有”方法,则只需要某种方式向编译器显示这些方法的存在。我最喜欢的模式是在一个单独的文件中声明一个Category中的私有方法(比如MyClass_private.h)。然后,您只将该接口导入基类的实现文件以及需要查看它的任何派生类。

答案 1 :(得分:2)

我有一个解决方案,但通常我会反对它。如果使用-w编译文件(禁止所有警告),警告就会消失。我不知道此消息是否有特定的警告标志,如果有,您可以使用#pragma GCC diagnostic ignored "-Winstance-method-not-found",但我找不到,抱歉。