[IPhone] UIView与内存管理

长平狐 发布于 2012/10/08 15:19
阅读 135
收藏 0

Introduction
Memory management in the Iphone is a hot topic.
I might as well share some tips here from my own experience.

Background
I got a game project of iphone at the end of March, 2010.
Then I started to study development in Iphone with Object-C and C++.
I developed a library that named CloudBox and used to develop my project of game.
In the past, I had met many times of crash, the reason was issue of memory management.

Sample 1

UIImage *tmp = [UIImage imageNamed:@"logo.png"]; // imageNamed will return an autorelease object
bigpicture = [[UIImageView alloc] initWithImage:tmp];
//[tmp release];
// if you release a autorelease object, you application may be crash.
// so it dose not need release

Avoid using autorelease object.
If you use an autorelease object, you can not control when it was released.
And if you release an autorelease object by yourself, sometimes might cause crash.
[NSxxx xxxGenerate] naming function will return an autorelease object, like [UIImage imageNamed] or [NSString stringWithFormat].

Sample 2

class SuccessView
{
private:
    UIImageView* m_View;
public:
    SuccessView(UIView* parentView);
    ~SuccessView();
};
SuccessView::SuccessView(UIView* parentView)
{
    m_View = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 100.0)];
    // after alloc, m_View's retainCount = 1
    [parentView addSubView:m_View];
    // after addSubView, m_View's retainCount = 2
}
SuccessView::~SuccessView()
{
    [m_View removeFromSuperview];
    // after removeFromSuperview, m_View's retainCount = 1
    [m_View release];
    // after release, m_View's retainCount = 0, release success.
}
class CrashView
{
private:
    UIImageView* m_View;
public:
    CrashView(UIView* parentView);
    ~CrashView();
};
CrashView::CrashView(UIView* parentView)
{
    m_View = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 100.0)];
    // after alloc, m_View's retainCount = 1
    [parentView addSubView:m_View];
    // after addSubView, m_View's retainCount = 2
    [m_View release];
    // after release, m_View's retainCount = 1
}
CrashView::~CrashView()
{
    [m_View release];
    // this release may cause application crash.
}
class DemoSample
{
private:
    UIView* m_MainView;
    SuccessView* success;
    CrashView* crash;
public:
    DemoSample();
    ~DemoSample();
    void TestRemoveSuccessView();
    void TestRemoveCrashView();
};
DemoSample::DemoSample()
{
    m_MainView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 100.0)];
    success = new SuccessView(m_MainView); // draw success view on m_MainView
    crash = new CrashView(m_MainView); // draw crash view on m_MainView
}
DemoSample::~DemoSample()
{
    [m_MainView release];
}
void DemoSample::TestRemoveSuccessView()
{
    delete success; // it will success to remove this view from m_MainView
}
void DemoSample::TestRemoveCrashView()
{
    delete crash; // it will cause crash
}

In develop of game, I used random generate NPC.
If NPC dead, I will remove NPC on screen and release it.
In the past, I got a experience.
When I release UIImageView without removeFromSuperview, the application will crash.
I got some conclusions:
1. view = [UIImageView alloc] => view's retainCount = 1
2. [parentView addSubview:view] => view's retainCount = 2
3. [view removeFromSuperview] => view's retainCount = 1
4. [view release] => view's retainCount = 0

Reference
IPhone Memory Management
IPhone Memory Management Tips
Apple Document


原文链接:http://blog.csdn.net/cloudhsu/article/details/5754430
加载中
返回顶部
顶部