这是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}}都指的是相同的实例变量。
答案 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,因为该对象保留在那里而不是简单地指针指定。