用“ self.variable = value”两次设置实例变量会导致内存泄漏?
|
直到昨天,我还以为我已经了解了iPhone的内存管理。
好吧,这是我的问题:
// .h file
@property(nonatomic, retain) NSMutableDictionary *dicParams;
@property(nonatomic, retain) NSMutableDictionary *dicReferences;
@property(nonatomic, retain) FtMonitorHandler *monitorHandler;
// .m file
@synthesize dicParams, dicReferences, monitorHandler;
- (id)init {
self = [super init];
if (self) {
self.dicParams = [[NSMutableDictionary alloc] init];
self.dicReferences = [[NSMutableDictionary alloc] init];
self.monitorHandler = [[FtMonitorHandlerService alloc] init];
}
return self;
}
- (void)dealloc {
[monitorHandler release];
[dicParams release];
[dicReferences release];
[super dealloc];
}
如果我在其他地方设置,例如在分配视图控制器之后
self.dicParams = dicValues;
…会变成泄漏
我对使用\“ self。…\”设置实例变量的理解是,当前值将为\“ released \”,然后使用\“ retain \”进行设置。
我尝试了一些乐器。结果:
-(void)createLeak {
self.dicParams = [[NSMutableDictionary alloc] init];
self.dicParams = [[NSMutableDictionary alloc] init];
}
-(void)createAnotherLeak {
self.dicParams = [[NSMutableDictionary alloc] init];
self.dicParams = nil;
self.dicParams = [[NSMutableDictionary alloc] init];
}
- (void)createWithoutLeak {
if(dicParams != nil) [dicParams release];
self.dicParams = [[NSMutableDictionary alloc] init];
}
我是否错过了某些事情,或者这是应有的行为?
编辑:我试图实施建议的更改。只要我的变量不是GUI元素,它就可以正常工作。 (UIView,UILabel等)
内存警告后,自动释放会导致应用程序崩溃
- (void)loadView {
[super loadView];
// ... here is some other stuff ...
self.lblDeparture = [[[UILabel alloc] init] autorelease];
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
self.lblDeparture = nil;
}
- (void)dealloc {
[lblDeparture release];
[super dealloc];
}
我不太确定,但我认为以下几行是真正的问题:
CGRect frame = CGRectMake(0, 0, self.view.frame.size.width, INFO_VIEW_HEIGHT);
UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame];
[imageView addSubview:lblDeparture];
[lblDeparture release]; // is this correct?
[self.view addSubview:imageView];
[imageView release];
没有找到相关结果
已邀请:
5 个回复
姬第柔炒
等效的方法是使用便捷访问器。
如果您想自己解决这个问题。在@synthesize dictParams之上;您还需要创建自己的二传手。
这有点简单。但本质上是编译器在将保留修饰符添加到@property标记后创建的内容
挂帘妈乡
的实例变量,则保留计数变为1 现在,当您引用self时,例如“ self.variable = value”,将case8ѭ计数增加1,因此总保留计数变为2。 因此,现在要释放它,您需要将保留计数设为0。因此,您需要释放两次。 Hopew这会有所帮助。
冕偷淮款
很明显... 现在但是这个 -(void)createAnotherLeak {
不会释放第一个已分配的self.dicParams,而是通过将其设置为nil,然后用一个新值将其重置来忘记对它的任何引用。设置为nil不等于释放。如果您要使用自动发布功能创建第一个,然后将其设置为nil,那就有些不同了。那应该正常工作。这就是您对第三个示例所做的出色表现! 现在关于您的初始问题,当您撰写时泄漏了什么? self.dicParams = dicValues; ? 变量self.dicParams应该只保存该值,直到再次释放它为止
茬贺努充尽
或
中使用访问器。 所以这
应该
其次,当您设置保留属性时,您需要释放其设置的内容。 所以这
应该
或者你可以这样做
妒垮
为
属性生成的设置器如下所示:
由实例变量“ 23”指向的旧对象将被释放,而新对象将被保留。 您的错误是对象创建。您用
创建字典。该词典的保留计数为1。您的setter保留了该对象,因此新的保留计数为2。当您再次调用setter时,原始词典的保留计数将正确减少-再次为1。要释放字典,您必须再次释放它。为此,有25英镑。自动释放的对象将在一段时间后释放。所以设置属性的正确代码是
甚至更好的使用便利分配器
您确实应该阅读并理解Apple的内存管理指南-在那里进行了全部解释。 顺便说一句,我在这里谈到保留数。可以考虑它们,但是您永远不要问一个对象有关其保留计数的问题,该值是无用的,因为它很少能想到。