iPhone - 包括子视图和可能的内存泄漏?

发布于 2024-11-05 20:07:03 字数 590 浏览 1 评论 0原文

在编写此常见语句时:

UIViewController* viewController = [[UIViewController alloc] initWithNibName:@"myXIB" bundle:nil];
/* do some things with the viewController */
[self.view addSubview:viewController.view];

我想知道这里是否可能存在内存泄漏,因为:

  • 代码不会释放 viewController ,
  • 在将 viewController 插入到 self.view 中后,调用 [viewController release] 的
  • 从而导致应用程序崩溃viewController 不被自己所知.view 因为它不是直接插入的,所以释放 self.view 不应该释放 viewController

所以我在这里看到内存泄漏,viewController 永远不会被释放。

您能给我您的专业知识吗?

注意:Instruments 没有发现任何内存泄漏。

When writing this common statements :

UIViewController* viewController = [[UIViewController alloc] initWithNibName:@"myXIB" bundle:nil];
/* do some things with the viewController */
[self.view addSubview:viewController.view];

I'm wondering if there is a possible memory leak here, because :

  • viewController is not released by code
  • calling [viewController release] after having inserted it in self.view makes the app crash
  • viewController is not known by self.view because it is not directly inserted, so releasing self.view should not release viewController

So I see a memory leak here where viewController is never released.

Could you give me your expert knowledge about that ?

Note : Instruments does not find any memory leak there.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

那伤。 2024-11-12 20:07:03

如果您希望视图作为子视图,我认为最好将视图控制器作为类的实例变量,并在 dealloc

UPDATE 中释放它。取自

之前的SO问题

仪器的泄漏检测工作原理是
保守地扫描内存,
寻找指针并构建
之间的连接图
分配。如果发现任何
指向内存中对象的指针
可以从全局变量访问
或堆栈变量,然后是该对象
不能视为泄露。

仪器不知道布局
或指针的上下文。如果你是
到 malloc(1024) 并且发生了
是一堆指针
[回收]内存块,那些
会算数,即使你永远不会
将这些指针视为真实的
再次参考。

所以,不,泄漏永远不可能是 100%
准确的。同样,还有更多
泄漏内存的方法比
实际泄漏。

If you want view as a sub view I think its only better to have the view controller as an instance variable of the class and release it in dealloc

UPDATE

Taken from a previous SO question

Instrument's leak detection works by
conservatively scanning memory,
looking for pointers and building a
graph of connections between
allocations. If it finds any
pointer(s) to an object in memory that
can be reached from a global variable
or stack variable, then that object
cannot be considered leaked.

Instruments does not know the layout
or context of a pointer. If you were
to malloc(1024) and there happened to
be a bunch of pointers in that
[recycled] chunk of memory, those
would count even though you will never
treat those pointers as real
references again.

So, no, Leaks can never be 100%
accurate. As well, there are far more
many ways to leak memory than an
actual leak.

掩于岁月 2024-11-12 20:07:03

是的,内存会泄漏,你应该总是释放自己分配的内存。
当您添加[viewController release]时,viewController会立即释放,然后您的应用程序崩溃,因为它正在尝试访问已释放的内存。为了防止这种情况,您应该将 viewController 作为类的实例变量包含在内。

Yes, memory will leak, you should always release memory allocated by yourself.
When you add [viewController release] the viewController is dealloced immediately and then your app crashes, because it's trying to access dealloced memory. To prevent it, you should include your viewController as instance variable of your class.

西瓜 2024-11-12 20:07:03

当您分配一个新的 UIViewController 但从未释放它时,这里肯定存在泄漏(当您进行分配时,它不会添加到自动释放池中)。您必须保留对此 viewController 对象的引用并稍后释放它。

正如您所说,如果您在 [viewController release] 之​​后立即调用,它确实会使您的应用程序崩溃,因为您刚刚将其内部视图添加到 self.view 但该视图(viewController)所属的控制器的引用计数器尚未增加。

There is definitely a leak here as you allocate a new UIViewController but never release it (it is not added to the autorelease pool as you do an allocation). You have to keep a reference on this viewController object and release it later on.

As you said, if you call right after [viewController release], it does crash your application because you have just added its internal view to self.view but the reference counter of the controller to which this view (viewController) belongs has not been incremented.

淡莣 2024-11-12 20:07:03

Tableview didselrowatindex 方法是发生此类内存泄漏的常见地方。

消除内存泄漏的一种方法是确保只创建 ViewController 的一个实例,然后重用它。

此外,这种技术不仅适用于创建和显示视图控制器,还适用于任何事物。如果您在代码中创建任何内容(例如 uilabel 等),请确保您没有创建多个实例。

/* 代码 */

// in the interface create an ivar ... or a property if needed
UIViewController *childViewController;

/// 然后在你的代码中,tableview didSelectRow 等

// don't create multiple instances of the VC, rather, check to see if we can reuse one
if (! childViewController)
{
   childViewController = [[UIViewController alloc] init];
}

// do some things with the viewController 
childViewController.someProperty = someValue;
[self.view addSubview:childViewController.view];

Tableview didselrowatindex method is a common place where such memory leaks occur.

One way to do away with memory leaks is to make sure you only create one instance of the ViewController and then reuse it.

Furthermore this technique doesn't just apply to creating and showing viewcontrollers but anything. If you are creating anything in code such as uilabels, etc, make sure that you are not creating multiple instances.

/* code */

// in the interface create an ivar ... or a property if needed
UIViewController *childViewController;

/// then later in your code , tableview didSelectRow, etc

// don't create multiple instances of the VC, rather, check to see if we can reuse one
if (! childViewController)
{
   childViewController = [[UIViewController alloc] init];
}

// do some things with the viewController 
childViewController.someProperty = someValue;
[self.view addSubview:childViewController.view];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文