如何使inheritance的类能够在Objective-C中查看父类的隐藏方法

我有两个类,Class1和Class2,第二个从第一个inheritance。 我需要重写Class1的-update方法来实现我的目标。 inheritance方法中的-update方法的变化是在代码中间执行的,所以我不能使用[super update]。 这就是为什么我需要将原始方法从父级复制粘贴到inheritance类。 这个方法使用了父类的私有方法,所以当我试图重写时,我得到了私有方法缺失的警告,因为Class2只导入Class1.h。 为了澄清,这里是代码:

Class1.h:

@interface Class1 : NSObject -(void) update; @end 

Class1.m:

 @interface Class1 (Private) -(void) private1; -(void) private2; @end @implementation Class1 -(void) update { [self private1]; [self private2]; } -(void) private1 { // some code } -(void) private2 { // another code } @end 

Class2.h:

 @interface Class2 : Class1 -(void) update; @end 

Class2.m:

 @implementation Class2 -(void) update { [self private1]; // warning here // do my own stuff between private methods, that is the reason of inheritance [self private2]; // warning too } @end 

另外, Class1不在我的所有权范围内 ,而是来自开源库(Cocos3D,准确而言),所以我不能改变它 (这就是为什么我要inheritance的原因)。

问题是:我如何删除警告? 我可以看到唯一的解决scheme是将私有方法的签名复制到Class2,但它似乎是一个肮脏的伎俩。 或者,如果有人不指出如何去除警告,那将是完美的,但是如何更好地实现我改变方法的目标。

不需要swizzling,performSelector:或者任何其他的运行时间错误。

只要移动或复制这个:

 @interface Class1 (Private) -(void) private1; -(void) private2; @end 

到您的子类的.m文件的开头。

通常情况下,当试图为方法实现类似@protected作用域时,这样的声明将会在类似Class1_Private.h的头文件中,并且该头将被设置为Xcode中的privateangular色。

正如其他人所指出的,通过这种机制暴露私有方法是有点危险的。 鉴于Cocos2D是开源的,这种危险有所缓解,或者你可以直接修改它。 当然,这样做意味着你实际上有一个分支,维护成本很高。

如果这是其他开发人员可能做的事情,我会build议用Cocos2D提交一个错误,要求将这些方法暴露给子类。

苹果公司这样做的方式是使任何可以在子类中被覆盖的方法公开,但是logging下它们不应该被直接调用的事实,而只是被覆盖。 苹果代码的文档(通常)是全面的,经常提到,所以这个工作。 当然,典型的第三方代码没有很好的文档logging,也没有可能被阅读的文档…

另一个解决scheme:我经常创build一个名为“MyClass + SubclassMethods.h”的第二个头,并公开声明子类可覆盖的,但在其他类中有私有方法。 在基类和子类的用户的源文件中,这不是导入的,所以这些方法保持(有效)私有。 在基类的子类中,我导入“MyClass + SubclassMethods.h”以允许我重写/调用这些方法。 这不是一个完美的解决scheme,但是在Objective-C中没有“保护”方法的概念,我不确定是否有更好的方法。

一个类别,如另一个回应build议是一个很好的解决scheme,因为Class1不能被修改。 如果可以对源代码进行调整,则在单独的头文件中声明的类扩展和在Class1实现和Class2实现文件中的#imported将是方式,因为那样您不仅可以共享私有方法,还可以共享实例variables标记@public或@protected这种方式。 从这里了解更多关于类扩展的信息:

http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html

简而言之,类扩展有点像类(有时称为私有类),但它只能在扩展类所在的同一个编译单元中声明,并且可以声明(和自动合成)属性和实例variables。 Xcode中包含一个用于创build类扩展的源代码模板(参见下文)。

在Xcode中创建类扩展

你应该能够解决这个问题,使用类别来扩展你的原始类,并尝试方法调合,以达到你想要的行为。