Objective-C:扩展UIViewController导致意想不到的“自我”和“超级”感

时间:2013-03-01 01:24:49

标签: java ios uiviewcontroller

假设我有一个UIViewController

@interface CustomController : UIViewController 
@end

@implementation CustomController

- (void)myMethod {
     //this is the problematic line. It calls viewDidLoad of ExtendedController
     //but it should be calling viewDidLoad of CustomController
     [self viewDidLoad]; 
}

- (void)viewDidLoad {
   //and this line should call viewDidLoad from UIViewController
   [super viewDidLoad];
}

然后我有另一个延伸那个

@interface ExtendedController : CustomController
@end

@implementation ExtendedController

- (void)viewDidLoad {
   [super myMethod];
}

当启动ExtendedController时,它调用ExtendedController中的viewDidLoad,然后调用CustomController的myMethod,然后调用ExtendedController的viewDidLoad,这是一个无限循环。

如何使它成为CustomController的myMethod始终在CustomController类中调用viewDidLoad,而不是任何其他类。

这对我来说没什么意义,因为在Java中,例如,这个设置按预期工作。但不知何故,在iOS中扩展类时,“自我”的概念就会丢失。

public class Hello extends Omg {
   public void myMethod() {
      //in Java, this method does indeed call "viewDidLoad" in "Hello"
      this.viewDidLoad();
   }

   public viewDidLoad() {
      //in Java, this method does indeed call "viewDidLoad" in class "Omg"
      super.viewDidLoad(); 
   }
}

public class ExtendedHello {
   public void viewDidLoad() {
      super.viewDidLoad();
   }
}

如何修复iOS代码以获得预期的行为?

更新:请注意,“viewDidLoad”可以被任何方法名称替换......这个问题与它是viewDidLoad无关。

谢谢!

1 个答案:

答案 0 :(得分:0)

这正是它在Objective C中的工作方式。当你调用[self viewDidLoad]时,它实际上是在调用objc_msgSend(self,@ selector(viewDidLoad),...),它使用'self'(在这种情况下恰好是ExtendedController的一个实例,以查找要执行的实际函数。简而言之,'self'是实际类的一个实例,所以如果一个超类定义了那个函数,那就是那个将被调用的函数。

顺便说一下,调用viewDidLoad可能没有意义,因为那是在特定时间自动调用的。