这是苹果iPhone"实用应用程序"模板中未经修改的代码:

- (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而第二种情况下不需要self吗?我假设在这两种情况下,mainViewController都引用同一个实例变量.

推荐答案

使用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"方法小得多,但直接访问仍然可能会 destruct future 版本的Cocoa Touch.

Objective-c相关问答推荐

NSViewController 中的 viewDidLoad?

警告:格式字符串不是字符串文字(可能不安全)

在 ARC 之后,我应该为调度队列使用什么属性?

为什么 UITableViewCell Select 时所有背景都消失了?

iOS 块和对自身的强/弱引用

如何使用 NSString drawInRect 使文本居中?

isEqualTo: 和 isEqual 之间的区别:

如何知道 NSAssert 在发布版本中是否被禁用?

try 标记应用程序图标但未获得用户标记应用程序的权限:iOS 8 Xcode 6

你如何安排一个块在下一次运行循环迭代中运行?

在 iOS 中创建带有 URL 的 UIImage

以流畅的动画显示/隐藏导航栏

如何推送两个视图控制器但只为第二个设置动画过渡?

判断 NSString 是否仅包含字母数字 + 下划线字符

Modal segue,导航栏消失

在 Objective-C 中_和touch之间的区别

ARC时代的财产与ivar

在 iOS UILabel 上设置 BOLD 字体

在objective c中以自定义格式获取当前时间

NSString 中子字符串的出现次数?