Objective-C - 何时使用'self'

时间:2010-03-05 10:24:59

标签: iphone objective-c cocoa-touch

这是Apple的iPhone“Utility Aplication”模板中未经修改的代码:

- (void)applicationDidFinishLaunching:(UIApplication *)application {

 MainViewController *aController = [[MainViewController alloc] initWithNibName:@"MainView" bundle:nil];
 self.mainViewController = aController;
 [aController release];

 mainViewController.view.frame = [UIScreen mainScreen].applicationFrame;
 [window addSubview:[mainViewController view]];
 [window makeKeyAndVisible];

}

mainViewController分配给aController时,会指定self关键字:

 self.mainViewController = aController;

但是,设置mainViewController的框架后,不需要self关键字:

 mainViewController.view.frame = [UIScreen mainScreen].applicationFrame;

如果我从第一个示例中删除self关键字,程序会崩溃并显示以下消息:

objc[1296]: FREED(id): message view sent to freed object=0x3b122d0

如果我将self关键字添加到第二个示例,则程序运行正常。

有人可以解释为什么在第一种情况下需要self而在第二种情况下不需要mainViewController?我假设在两种情况下{{1}}都指的是相同的实例变量。

2 个答案:

答案 0 :(得分:49)

使用self会调用此类的“setter”来调用此变量,而不是直接更改ivar。

self.mainViewController = aController;

相当于:

[self setMainViewController:aController];

另一方面:

mainViewController = aController;

直接更改mainViewController实例变量,跳过可能构建到UIApplication的setMainViewController方法中的任何其他代码,例如释放旧对象,保留新对象,更新内部变量等等。

在你访问框架的情况下,你仍然在调用一个setter方法:

mainViewController.view.frame = [UIScreen mainScreen].applicationFrame;

扩展为:

[[mainViewController view] setFrame:[[UIScreen mainScreen] applicationFrame]];

理想情况下,为了将来验证您的代码,您还应该在检索此值时使用self.mainViewController(或[self mainViewController])。一般来说,类在“getter”方法中使用重要代码的可能性要小于“setter”,但是直接访问仍然可能会在未来版本的Cocoa Touch中破坏某些内容。

答案 1 :(得分:11)

self关键字表示您正在使用属性getter / setter而不是直接访问该值。如果您使用同步自动生成getter / setter,则必须在第一个示例中使用self,因为该对象保留在那里而不是简单地指针指定。