在Objective C类别中使用Super?

Bra*_*rks 24 objective-c super categories

我想覆盖Objective C类中我没有源代码的方法.

我已经研究过了,看来Categories应该允许我这样做,但是我想在我的新方法中使用旧方法的结果,使用super来获得旧方法的结果.

每当我尝试这个时,我的方法被调用,但"超级"是零...任何想法为什么?我正在使用XCode 2.2 SDK进行iPhone开发.我肯定在使用类的实例,类的方法是实例方法.

@implementation SampleClass (filePathResolver)
-(NSString*) fullPathFromRelativePath:(NSString*) relPath
{
    NSString *result = [super fullPathFromRelativePath: relPath];

  ... do some stuff with the old result

    return result;
}
Run Code Online (Sandbox Code Playgroud)

注意和澄清:从我在Apple Docs中看到的情况来看,在我看来应该允许这样做?

developer.apple.com上的类别文档: 当类别覆盖继承的方法时,类别中的方法可以像往常一样通过消息调用继承的实现到超级.但是,如果某个类别覆盖了类别类中已存在的方法,则无法调用原始实现.

Geo*_*lly 29

Categories扩展了原始类,但是它们没有对它进行子类化,因此调用时super找不到该方法.

你想要什么称为方法调配.但请注意,您的代码可能会破坏某些内容.有一篇关于Theocacao的文章由Scot Stevenson在旧的Objective-C运行时编写有关Method Swizzling的内容,Matt Gallagher的Cocoa with Love在新的Objective-C 2.0运行时中有一篇关于Method Swizzling的文章,并简单地替换它.

或者,您可以继承该类,然后使用子类或使用+ (void)poseAsClass:(Class)aClass替换超类.Apple写道:

由冒充类定义的方法可以通过消息来super合并它覆盖的超类方法.

请注意,Apple已poseAsClass:在Mac OS X 10.5中弃用.

  • @ Brad Parks:这意味着`[super message]`被发送到超类,并且不会调用被覆盖的方法. (2认同)
  • @brian:苹果甚至在实施KVO时也是如此. (2认同)

Jas*_*son 8

如果您将对此类进行编码,只需将选择器重命名为您的代码可以使用的内容,然后调用原始选择器self:

@implementation SampleClass (filePathResolver)
-(NSString*) myFullPathFromRelativePath:(NSString*) relPath
{
    NSString *result = [self fullPathFromRelativePath: relPath];

  ... do some stuff with the old result

    return result;
}
Run Code Online (Sandbox Code Playgroud)

如果要覆盖该类的此选择器的默认实现,则需要使用方法调整方法.