内存管理 [英] Memory Management

查看:111
本文介绍了内存管理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何方法removeFromSuperView:真的有效?
当我想重新启动视图时,遇到内存不正确的问题。

   - (id)init {
if(!(self = [super init]))
return nil;

_mainView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
NSLog(@retainCount:%d,[_mainView retainCount]);
UIButton * reInitButton = [[UIButton alloc] initWithFrame:CGRectMake(0.0f,0.0f,90.0f,35.0f)];
[reInitButton addTarget:self action:@selector(buttonDidTapped :) forControlEvents:UIControlEventTouchUpInside];
[[self view] addSubView:_mainView];
NSLog(@retainCount:%d,[_mainView retainCount]);
[_mainView release];
NSLog(@retainCount:%d,[_mainView retainCount]);

return self;
}

- (void)buttonDidTapped:(id)sender {
[_mainView removeFromSuperView]; //第二次崩溃按下按钮
NSLog(@retainCount:%d,[_mainView retainCount]);
_mainView = [[UIView alloc] initWithFrame [[UIScreen mainScreen] bounds]];
[[self view] addSubView:_mainView];
NSLog(@retainCount:%d,[_mainView retainCount]);
[_mainView release];
NSLog(@retainCount:%d,[_mainView retainCount]);
}



每次有NSLog都有任何retain或alloc或release关键字。结果很奇怪。

  // init 
retainCount:1
retainCount:2
retainCount:1
//第一次按下按钮
retainCount:1 //删除超级视图没有减少
retainCount:2
retainCount:1
/ /第二次按下按钮
retainCount:0 //崩溃。内存不好的访问

奇怪的是为什么它没有崩溃第一次按? p>

解决方案

我认为你的问题在这里:

  [_ mainView release]; 

您已删除对 _mainView ,然而,通过我的阅读,这是一个成员变量,你会保持和继续调用方法。这是无效的。一旦你调用 -release ,你基本上告诉系统你不会再使用那个对象,你不能

$

$ p>如果你想继续保持 _mainView ,并在它上面调用代码,你需要保留一个引用。也许你应该将发布移动到你的对象的 -dealloc 方法。或者,您可以在按钮方法中 -release ,并在下次需要时重新创建新视图。



作为一个有用的提示,很多程序员喜欢将objC中的对象重置为 NULL (或 nil ),释放它们后,作为提醒,您不能再次使用该对象。如果你 -release 某事,你最好是意味着。



最后,我建议你谷歌的参考计数并读取它;它是一个更通用的成语比 NSObject 的细节,并且它可能是有用的想法的基础和如何实现这个在另一种语言,如说,C这将帮助你更好地推理引用计数对象。


How is method removeFromSuperView: really works? I got a problem of memory bad access when I want to reinit the view

- (id)init {
   if (!(self = [super init]))
      return nil;

   _mainView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
   NSLog(@"retainCount :%d", [_mainView retainCount]);
   UIButton *reInitButton = [[UIButton alloc] initWithFrame:CGRectMake(0.0f,0.0f,90.0f,35.0f)];      
   [reInitButton addTarget:self action:@selector(buttonDidTapped:) forControlEvents:UIControlEventTouchUpInside];
   [[self view] addSubView:_mainView];
   NSLog(@"retainCount :%d", [_mainView retainCount]);
   [_mainView release];
   NSLog(@"retainCount :%d", [_mainView retainCount]);

   return self;
}

- (void)buttonDidTapped:(id)sender {
   [_mainView removeFromSuperView]; //crash during second times press the button
   NSLog(@"retainCount :%d", [_mainView retainCount]);
   _mainView = [[UIView alloc] initWithFrame[[UIScreen mainScreen] bounds]];
   [[self view] addSubView:_mainView];
   NSLog(@"retainCount :%d", [_mainView retainCount]);
   [_mainView release];
   NSLog(@"retainCount :%d", [_mainView retainCount]);
}

I have NSLog every times there are any retain or alloc or release keyword. And the result is very weird.

//init
retainCount : 1
retainCount : 2
retainCount : 1
//1st time pressed button
retainCount : 1 //remove super view didn't decrease
retainCount : 2
retainCount : 1
//2nd time pressed button
retainCount : 0 //crash. Memory bad access

The weird thing is why it didn't crash on 1st time pressed??

解决方案

I think your problem is here:

[_mainView release];

You've dropped your reference to _mainView, and yet, by my reading, that's a member variable that you'll keep around and continue to invoke methods on. That's not valid. Once you've called -release, you've essentially told the system you're not going to use that object again, and you can't do anything useful with a stale pointer to that object, like you do when you call -removeFromSuperView on it later.

If you want to continue to keep _mainView around and call code on it, you need to keep a reference. Perhaps you should move the release to your object's -dealloc method. Alternatively you could -release it in the button method and re-create a new view the next time you need to.

As a helpful tip, a lot of programmers like to reset objects to NULL (or nil in objC-speak) after releasing them, as a reminder that you can't use that object again. If you -release something, you'd better mean it.

Lastly, I suggest you Google the term "reference counting" and read up on it; it's a more generic idiom than the specifics of NSObject, and it is likely to be useful to think of the basics and how you might implement this in another language, like say, C. This will help you reason better about reference counted objects.

这篇关于内存管理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆