Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >内存管理

内存管理
EN

Stack Overflow用户
提问于 2011-05-15 05:07:14
回答 2查看 583关注 0票数 1

方法removeFromSuperView:是如何工作的?当我想要重新启动视图时,我遇到了内存访问错误的问题

代码语言:javascript
运行
AI代码解释
复制
- (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]);
}

每当有任何保留、分配或释放关键字时,我都会使用NSLog。结果非常奇怪。

代码语言:javascript
运行
AI代码解释
复制
//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

奇怪的是,为什么它在第一次按下时没有崩溃??

EN

回答 2

Stack Overflow用户

发布于 2011-05-15 05:13:43

从不使用RETAINCOUNT。很抱歉把它放在大写字母里,但我真的搞不懂为什么人们还在用它。这是一个错误的内存管理参考。请使用仪器或类似的工具。

票数 3
EN

Stack Overflow用户

发布于 2011-05-15 05:33:21

此时您不应该访问_mainView。这可能很难解释,所以请容忍我。我们将计数,但不是绝对的保留计数,只是你的代码对对象的声明。

您可以为对象分配内存,并使用_mainView指向该对象

代码语言:javascript
运行
AI代码解释
复制
_mainView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

您对该对象有1个所有权声明。当你将其添加为另一个视图的子视图时,该视图同样会声明所有权,但这不是你的,而是视图的。它让_mainView中的对象停留在那里的事实是一个意外,你不应该依赖它。然后释放对象:

代码语言:javascript
运行
AI代码解释
复制
[_mainView release];

您已放弃所有权声明--您现在有0个声明,您不应再尝试访问此对象。你不拥有它。同样,它仍然存在是因为另一个视图正在使用它,以及您仍然有指向它的指针,这都是偶然的*,您不应该依赖它们。

然后,当需要处理按钮按下时,您访问的是一个您没有所有权的对象:

代码语言:javascript
运行
AI代码解释
复制
[_mainView removeFromSuperView];

这会导致崩溃,这可能是意想不到的,但也不是不合理的。通过让你的所有权声明变为0,你告诉系统“我不再需要这个对象了。在这之后我不会再访问它了。如果它消失了,我不会受到影响。”但实际上,您确实需要它留在周围,并且您确实需要访问它。

那么,你应该做的就是移动这行:

代码语言:javascript
运行
AI代码解释
复制
[_mainView release];

添加到按钮操作内部,就在调用removeFromSuperview之后。

*第二个问题可以通过在释放后设置_mainView = nil;来避免,在这种情况下,但这不会解决更大的问题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6006603

复制
相关文章
ios内存管理-内存管理范围
1、栈区(stack) — 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。 2、堆区(heap) — 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 3、全局区(静态区)(static)— 全局变量和静态变量的存储是放在一块的,初始化的 全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域, 程序结束后由系统释放。 4、常量区 — 常量字符串就是放在这里的。 程序结束后由系统释放。 5、程序代码区 — 存放函数体的二进制代码。
赵哥窟
2018/09/13
1.4K0
ios内存管理-内存管理范围
内存管理专栏 | 之内存管理架构
一、内存管理架构 二、虚拟地址空间布局架构 三、物理内存体系架构 四、内存结构 五、内存模型 六、虚拟地址和物理地址的转换 七、内存映射原理分析 一、内存管理架构 内存管理子系统架构可以分为:用户空间、内核空间及硬件部分3个层面,具体结构如下所示:1、用户空间:应用程序使用malloc()申请内存资源/free()释放内存资源。2、内核空间:内核总是驻留在内存中,是操作系统的一部分。内核空间为内核保留,不允许应用程序读写该区域的内容或直接调用内核代码定义的函数。3、硬件:处理器包含一个内存管理单元(Memo
刘盼
2022/09/02
1.5K0
内存管理专栏 | 之内存管理架构
Android内存管理(八)内存管理小结
今天从操作系统的角度来闲聊一下代码开发过程中如何配合系统做内存管理。内存就是一块数据存储区域,是可被操作系统调度的资源。在多任务(进程)的OS中,内存管理尤为重要,OS需要为每一个进程合理的分配内存资源。所以可以从OS对内存和回收两方面来理解内存管理机制。
Anymarvel
2020/09/23
1.6K0
Android内存管理(八)内存管理小结
Android内存管理(三)内存管理基础
CPU只能访问其寄存器(Register)和内存(Memory), 无法直接访问硬盘(Disk)。存储在硬盘上的数据必须首先传输到内存中才能被CPU访问。从访问速度来看,对寄存器的访问非常快,通常为1纳秒;对内存的访问相对较慢,通常为100纳秒(使用缓存加速的情况下);而对硬盘驱动器的访问速度最慢,通常为10毫秒。
Anymarvel
2020/09/23
1.6K0
Android内存管理(三)内存管理基础
[C++]内存管理
2.内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。
IT编程爱好者
2023/04/30
8780
[C++]内存管理
内存管理
一、管理方式 1、连续分配 (1)单一连续分配:分配到内存固定区域,只适合单任务系统。 (2)固定分区分配:分配到内存中不同的固定区域,分区可以相等,也可以不等 (3)动态分区分配: 基本概念:按照程序的需要进行动态的划分 分配算法: ①首次适应:地址从小到大为序,分配第一个符合条件的分区。 ②最佳适应:按空间从小到大为序,分配第一个符合条件的分区。 ③最坏适应:按地址从大到小为序,分配第一个符合条件的分区。 ④临近适应:与首次适应相似,从上次查完的结束位置开始查找。 2、非连续分配 (1)基本分页:内存分
week
2018/08/27
6660
内存管理
进程调度能提高CPU利用率和计算机响应速度。为了实现这一性能,必须将多个进程保存在内存中,也就是说内存共享。
zy010101
2019/07/10
6940
内存管理
1)将内存看做缓存,内存中存储此时正在运行的数据,其他数据存到磁盘,当需要使用时再换入内存,内存不够时将不用的换出到磁盘。
你的益达
2020/08/19
8020
内存管理
* 存储对象的堆空间内存: 当内存没有引用指向时, 对象成为垃圾对象, 垃圾回收器后面就会回收释放此内存
李才哥
2020/03/28
4870
Java学习笔记——内存管理Java内存管理
Java内存管理 简介 Java虚拟机的内存管理分为以下几个运行时数据区: 方法区 堆 虚拟机栈 本地方法栈 程序计数器 其中,方法区和堆是所有线程共享的数据区,而其他的是线程隔离的数据区。 堆 Java堆,又称GC堆,是GC的管理的主要区域。在虚拟机启动时创建。主要作用是存放对象实例,几乎所有的对象实例都会存放在Java堆中。Java堆可以处于物理不连续的内存空间中,只要逻辑连续即可。通常Java堆是可扩展的。当Java堆无法申请到所需的内存空间来存放实例,也无法扩展时,会抛出,OutOfMemoryEr
Oceanlong
2018/07/03
1.5K0
Go 语言内存管理(一):系统内存管理
要搞明白 Go 语言的内存管理,就必须先理解操作系统以及机器硬件是如何管理内存的。因为 Go 语言的内部机制是建立在这个基础之上的,它的设计,本质上就是尽可能的会发挥操作系统层面的优势,而避开导致低效情况。
李海彬
2019/05/08
2.4K0
Go 语言内存管理(一):系统内存管理
Go 语言内存管理(二):Go 内存管理
了解操作系统对内存的管理机制后,现在可以去看下 Go 语言是如何利用底层的这些特性来优化内存的。Go 的内存管理基本上参考 tcmalloc 来实现的,只是细节上根据自身的需要做了一些小的优化调整。
李海彬
2019/05/08
7.4K0
Go 语言内存管理(二):Go 内存管理
5.Block的内存管理 内存管理内存管理block的循环引用
内存管理 ---- 无论当前环境是ARC还是MRC,只要block没有访问外部变量,block始终在全局区 MRC情况下 block如果访问外部变量,block在栈里 不能对block使用retain,否则不能保存在堆里 只有使用copy,才能放到堆里 ARC情况下 block如果访问外部变量,block在堆里 block可以使用copy和strong,并且block是一个对象 block的循环引用 ---- 如果要在block中直接使用外部强指针会发生错误,使用以下代码在block外部实现可以解决 __w
陈雨尘
2018/06/01
8370
操作系统 内存管理 内存存储管理方案
固定分区是指系统先把内存划分为若干个大小固定的分区,一旦分配好,在系统运行期间便不再重新划分。程序运行时必须提供对内存资源的最大申请量。
Meng小羽
2019/12/23
1.5K0
JVM内存管理------JAVA语言的内存管理概述
引言 内存管理一直是Java语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑。不过世界上不存在十全十美的好事,在带来了便利的同时,也因此引入了很多令人抓狂的内存溢出和泄露的问题。 可怕的事情还不只如此,有些使用其它语言开发的程序员,给JAVA程序员扣上了一个“不懂内存”的帽子,这着实有点让人难以接受。毕竟JAVA当中没有malloc和delete、没有析构函数、没有指针,刚开始接触JAVA的程序员们又怎么可能接触内存这一部分呢,更何况有不
用户1257215
2018/01/30
9460
JVM内存管理------JAVA语言的内存管理概述
Python 内存管理机制及手动内存管理
在编程过程中,优化程序的性能是一个常见的需求。而内存管理是一个关键的方面,可以对程序的性能产生重大影响。Python作为一种高级的解释型语言,自带了内存管理机制,同时也提供了手动管理内存的能力。本文将介绍Python中的内存管理机制,并探讨如何手动进行内存管理。
疯狂的KK
2023/08/06
5350
Python 内存管理机制及手动内存管理
JVM内存管理
一:  首先弄明白两个概念:物理内存和虚拟内存   物理内存:通常所说的RAM(随机存储器),有一个存储单元寄存器,存储计算单元执行指令的中间结果。物理内存是真实存在的,例如:内存条   虚拟内存:利用磁盘空间虚拟出的一块逻辑内存,用作虚拟内存的磁盘被称作交换空间。虚拟内存保证多个线程同时执行时可以共享同一块物理内存。但只是空间上共享,逻辑上不是共享的,而且相互支架不能直接访问。 二:       什么是内核?什么是用户空间? ·  内核是操作系统运行时所需要的内存,也就是系统空间。          用户
用户2146856
2018/06/26
5040
Redis内存管理
在Redis中删除数据之后,可能会出现Redis占用的内存不释放的问题,今天我们来看看这个问题。
AsiaYe
2021/08/06
9530
java内存管理
java虚拟机在应用在执行的过程中将自己管理的内存分为5部分: 方法区,堆,虚拟机栈,本地方法栈,程序计数器
丁D
2022/08/12
5530
java内存管理
Linux内存管理
谈到内存管理,最先想到的就是分段和分页机制。计算机刚出现的时候,并没有这些,刚开始是直接使用的物理地址,也就是代码中操作的地址是可以直接和物理地址对应上的,可是后来随着多进程调度的需求,以及有限的物理内存,于是人们就开始做规定,比如对于一块内存,某个范围是属于内核,然后另外一个范围属于进程A,再另外一个范围属于进程B,如下图所示
一只小虾米
2023/03/19
13.9K0
Linux内存管理

相似问题

新内存管理和删除内存管理

40

内存管理

60

管理内存

11

内存管理

10

内存管理

39
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档