了解引用计数/内存和属性

时间:2011-09-09 20:30:51

标签: iphone ios

我的问题是 - 如果我错了,你能否纠正我?谢谢!

我能想到的最简单的例子是从头开始创建一个应用程序。删除MainWindow nib文件等。

// .h file of appDelegate
UIWindow* window_;

@property UIWindow* window;

// .m appDelegate
@synthesize window = window_
[window_ release] // dealloc method

让我们说在Application中完成了启动方法

{
// window is currently nil with a reference count of 0.

window_ [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]]; // window_ has a reference count of 1

MyViewController* myVC = [[MyViewController alloc] initWithNibName:nil bundle nil]; // myVC has a reference count of 1

UINavigationController* navCon = [[UINavigationController alloc] initWithRootViewController:myVC] // navCon reference count 1, myVC reference count of 2

//way 1
self.window.rootViewController = navCon; // navcon has a reference count still 1. however since self.window.rootViewController was nill, all is nice and dandy. if however, self.window.rootViewController was not nil there would be a memory leak
[myVC release]; // brings myVC down to 1, all is good and well;
[self.window makeKeyAndVisible];

//way 2
[self.window setRootViewController: navCon]; // releases self.window setRootViewController 1 to 0, then retains navController which brings it back to 1
[myVCrelease]; //onece again brought back to one
[navCon release]; //since it's reference count is 2 thanks to setRootViewController
[self.window.makeKeyAndVisible].
}
什么时候navCon最终会发布?应用关闭时?或者幕后会发生什么事吗?我的编程方式与你的风格相似吗?我应该使用很多self.window而不是window_吗?我应该使用很多setProperty而不是=?感谢您的时间!

}

3 个答案:

答案 0 :(得分:1)

几点:

当与它们关联的保留计数达到零时,会立即释放对象。

属性处理保留和释放,你绝对应该使用属性而不是与它们相关的原始变量(使用self.window而不是_window)。

不要试图跟踪原始计数,而是负责任地管理内存。因此,例如,每当您将myVC交给导航控制器时,都可以释放myVC,而不是在保留计数增加时释放。

如果你只是自动释放而不是手动释放,它也会更容易。不用担心。 autorelease非常简单,它只是调用release“later”,这实际上是在再次执行run循环时。基本上它让你更关心代码而不是内存管理。在块结束时没有其他人保留的东西将会为你释放。

这也符合Google针对Objective C建议的标准。请参阅http://google-styleguide.googlecode.com/svn/trunk/objcguide.xml

答案 1 :(得分:0)

我会在导航控制器初始化后立即释放myVC

UINavigationController* navCon = [[UINavigationController alloc] initWithRootViewController:myVC]
[myVC release];

第一种方式是泄漏navCon

我更喜欢第二种方式。

您应该始终使用这些属性。

答案 2 :(得分:0)

ivar管理

应使用属性创建所有ivars。 如果ivar仅用于本地课程,则应在class extension中声明。

所有属性都应使用带有前导下划线的阴影ivars进行合成。

所有IBOutlets都应具有retain属性。

所有BOOL属性都应该有一个is * getter。

所有delegate属性应为assign(如果在ARC下,则为weak

示例:

@property (nonatomic, retain) NSString *exampleString;
@property (nonatomic, retain) IBOutlet UILabel *exampleLabel;
@property (nonatomic, assign, getter=isExampleBool) BOOL exampleBool;

@synthesize exampleString = _exampleString;
@synthesize exampleLabel = _exampleLabel;
@synthesize exampleBool = _exampleBool;

init, dealloc, viewDidUnload

init方法

  • 属性ivars应直接设置,而不是通过属性设置。

  • 任何不应该设置为nil,0或NO的ivars都应该设置或 创建

dealloc方法中:

  • 应释放所有ivar对象,而不是通过属性将其值设置为nil

  • 所有委托对象都应设置为nil。

viewDidUnload

  • 应释放所有IBOutlets并设置为nil。