———————————————————————————————————————————

内存管理



(1)Objective-C的内存管理







栈区    存放局部变量(由于基本数据类型占用的存储空间是固定的,由系统去分配,我们不用去管,故栈区存放基本数据类型,)



堆区    存放程序运行过程中动态分配的内存空间(对象类型是程序运行过程中动态分配的,他们的大小不固定。比如说是我们Person new申请来的,存放在堆区,也是我们需要管理的)



★所以内存管理的范围是   继承了NSObject的所有对象(堆区中的对象)

★这是为什么呢?因为代码执行完毕后,堆内存 不会自动释放(需要内存管理机制),而 栈内存 会自动释放(自动弹栈)



引用计数器     (一般用%ld或者%tu去查看里面的值,无符号的)



每个对象都有自己的引用计数器,它是一个整数表示对象被引用的次数,即现在有多少东西在使用这个对象,引用计数器的值变为0时,对象就销毁



①每一个对象刚生下来的时候,引用计数器都是1(对象一旦创建好,默认的引用计数器就是1)



②如果对象的引用计数器不为0,那么在整个程序的运行过程中,它占用的内存就不可能被回收(除非整个程序退出)



③当使用alloc、new或者copy创建一个对象时,对象的引用计数器默认就是1





(2)Objective-C的内存管理分类



Objective-C提供了三种内存管理的方式:



①Mannul Reference Counting(MRC,手动管理,在开发 iOS 4.1之前的版本项目时我们要自己负责使用引用计数来管理内存,比如手动retain、release、autorelease等。而在iOS之后的版本我们可以使用ARC,让系统自己管理内存)



②Automatic Reference Counting(ARC,自动引用计数,iOS 4.1后推出)



③Garbage Collection(垃圾回收,iOS不支持垃圾回收)



★苹果官方推荐我们使用ARC技术来管理内存,MRC理解就好





———————————————————————————————————————————

手动内存管理(MRC)



(1)首先我们要手动内存管理(MRC),就要先将自动管理关闭(关闭ARC)。



关闭ARC的方法:



点击项目(总的,蓝色)——> bulid setting ——> basic level ——>搜索 Objective-C Automatic Reference Counting ——> 此时会出现四个选项,全部设为 No 即可



(2)我们判断对象是否需要回收,这是就要查看引用计数器的值,需要调用

-(NSInteger)retainCount方法(这是一个有返回值的对象方法,返回值为NSInteger,NSInteger是一个动态类型,他的类型在不同的操作系统可能是int类型,也可能是long类型,他是有符号的。而NSUInerger是无符号类型,没有负数)



retainCount的返回值  > 0   不会回收

retainCount的返回值  = 0   回收内存空间



★注意:这里retainCount的返回值是 %tu 或者是 %ld 类型的~



(3)回收对象内存空间的时候通常会自动调用一个方法,dealloc(释放对象的属性)



我们可以通过重写dealloc这个方法来看看到底对象空间有没有被释放(再里面加一句话输出,如果释放了就会自动调用dealloc,那么这句话就会输出)



★★★这里注意重写dealloc和重写init不一样,要最后调用父类的dealloc方法,即最后调用 [super dealloc]; ,原因就是要先释放子类内存的再去释放父类的内存



(4)有两个对象方法可以使对象的引用计数器的值增加1和减少1



①使用 release  可以使引用计数  -1

②使用 retain     可以使引用计数  +1



(5)内存管理



我们应该心里有这么一个观念,就是让对象的引用计数保持一个平衡的状态



即:    retain + new = release  (增加引用计数=减少引用计数)





代码:



#import <Foundation/Foundation.h>



@interface Person : NSObject

-(void)run;

@end



#import "Person.h"



@implementation Person

- (void)dealloc

{

    NSLog(@"对象内存空间释放!");

    [super dealloc];//这句话一定要放在重写dealloc方法的最后一句,意义是:先释放子类占用的内存空间,再释放父类占用的内存空间(和重写构造方法正好相反,初始化对象时是先执行父类的init,再执行子类的初始化)

//    另外注意,永远不要直接调用dealloc方法,如果调用应该让retainCount = 0,但是如果你写 [p dealloc] 也是不会报错的,只是没有必要!这压根就是一个不需要你自己闲的蛋疼去写的一句话。

}

-(void)run

{

    NSLog(@"run!");

}

@end



int main(int argc, const char * argv[]) {

    @autoreleasepool {

        Person *p=[Person new];

        

        NSLog(@"p->retainCount = %tu",[p retainCount]);

//        这个地方因为创建了p,所以引用p的次数+1,所以输出的值为1。但是记住,这里必须将ARC关闭,如果不关闭是会报错的

        

        [p run];

        NSLog(@"p->retainCount = %tu",[p retainCount]);

//        这里输出结果还是1,因为 [p run]; 只是调用了run方法,但是p被引用的次数还是1

        

        [p release];

//        这里将引用计数-1,所以说此时引用计数为0,也就是此时将会自动调用dealloc方法,打印我们重写dealloc里面的“对象空间释放!”

         

        //        [p run];   //对象空间都释放了,但还是可以调用的,这是为什么呢?这个问题留在下节“单个对象的内存管理(野指针)去解释”            

   }

    return 0;

}





———————————————————————————————————————————

版权声明:本文为博主原创文章,未经博主允许不得转载。

Objective-C 【内存管理&手动内存管理 综述】的更多相关文章

  1. Objective-C中的内存管理——手动内存管理

    一.引用计数(retainCount) 1.内存的申请 alloc和new是Objective-C语言中申请内存的两种常用方式. 当我们向一个类对象发送一个alloc消息的时候,其会向操作系统在堆中申 ...

  2. iOS-旧项目中手动内存管理(MRC)转ARC

    在ARC之前,iOS内存管理无论对资深级还是菜鸟级开发者来说都是一件很头疼的事.我参 加过几个使用手动内存管理的项目,印象最深刻的是一个地图类应用,由于应用本身就非常耗内存,当时为了解决内存泄露问题, ...

  3. IOS基础 Day-1手动内存管理

    辞职回家打算自学IOS开发,就在借个地方记录一下 Day-1      手动内存管理                   主要内容:release  retain必须配对好,不然会占用内存 慢慢积累导 ...

  4. object-C 手动内存管理(MRC)

    object-C的内存管理和javascript的垃圾回收不一样,今天总结下手动内存管理,ARC的后边补上. 1:基本铺垫 oc采用引用计数来表示对象的状态,比如通过init创建出来的一个对象引用计数 ...

  5. Xcode 如何设置 自动内存管理 转换为 手动内存管理

    建议使用自动内存管理 ARC. 如果不想自动内存管理,可以在build phases 下的compile sources 中找到不想自动管理的.m文件 ,给它加compiler flags 为 -fn ...

  6. 【iOS开发-33】学习手动内存管理临时抛弃ARC以及retain/assign知识——iOSproject师面试必考内容

    我们为什么须要内存管理?当使用内存达到40M和45M时候会发出警告,假设不处理,占用内存达到120M时直接强制关闭程序. 所以出现闪退除了是程序出现逻辑错误,还有可能是内存使用过大. (1)创建一个对 ...

  7. C++ Primer : 第十二章 : 动态内存之动态内存管理(new和delete)

    C++语言定义了两个运算符来分配和释放动态内存:运算符new分配内存,运算符delete释放new分配的内存. 运算符new和delete 使用new动态分配和初始化对象 在自由空间分配的内存是无名的 ...

  8. Oracle DB 自动管理共享内存

    • 启用Oracle Enterprise Manager (EM) 内存参数 • 设置自动优化的内存参数 • 使用手动优化的SGA 参数覆盖最小大小 • 使用SGA Advisor 设置SGA_TA ...

  9. iOS的内存分析和内存管理

    iOS的内存分析和内存管理 [内存管理]一直是iOS开发中的一个重点. 本文就带你从内存分析开始一步步了解内存的占用情况,从真实的情况中领悟真正项目开发过程中的内存的使用情况. 注:本文默认你熟悉 M ...

随机推荐

  1. skyline TerraExplorer fly设置相对路径的方法

    软件环境:TerraExplorer Pro(以下简称TEP)6.5 在TEP中,对于本地(非网络)文件路径,默认都是绝对路径,在移动数据时非常麻烦,以下是本人总结出一些设置相对路径的规则 假设fly ...

  2. Spring连接数据库的几种常用的方式

    本文简单的讲解使用Spring连接数据库的几种常用方法: 测试主类为: package myspring2; import java.sql.*; import javax.sql.DataSourc ...

  3. ssh 设置免password登录

    如果: 实现->操作机A机 要以用户"user1"身份.免password登录B机和C机? B机和C机 建立用户 user1 而且能够ssh 登录. A机设置: 1.安装ss ...

  4. android SoundPool播放音效

    MediaPlayer的缺点: 资源占用量高,延时时间较长 不支持多个音效同一时候播放 SoundPool主要用于播放一些较短的声音片段,CPU资源占用率低和反应延时小,还支持自行色设置声音的品质,音 ...

  5. C#窗体间通讯的几种处理方法

    应用程序开发中,经常需要多窗体之间进行数据通信,写几个例子,把几种常用的通信方式总结一下: 主窗体Form1是一个ListBox,单击选中某列时,弹出窗体Form2,Form2中两个控件,一个是Tex ...

  6. w3cmark前端精彩博文周报 10.13-10.19

    w3cmark推出每周精选前端博文推荐,通过阅读别人的代码,学习别人的经验,提升自己的水平.欢迎关注 @前端笔记网 微博.其实如果是关注我们微博的朋友都对下面的文章熟悉,因为我们会一旦发现有价值的.精 ...

  7. HOW MYSQL USES INTERNAL TEMPORARY TABLES

    HOW MYSQL USES INTERNAL TEMPORARY TABLES Table of Contents [hide] 1)UNION queries 2)Some views 3)SQL ...

  8. unity工程接入Android sdk后真机测试解锁屏后退出的解决

    unity工程接入如91.移动支付等Android sdk后,真机运行尤其是在4.0+以上坏境,往往会出现解锁屏后退出的情况,解决办法如下: 可以在AndroidManifest.xml中所有的con ...

  9. Windows 10正式版官方原版ISO镜像下载

    [微软官方]下载地址1:官方下载工具(32-位系统版本)官方下载工具(64-位系统版本) [MSDN]下载地址2:cn_windows_10_multiple_editions_x64_dvd_684 ...

  10. java_类承继其他类的内部类例子

    package ming; class Outer { class In { public In(String msg) { System.out.println(msg); } } } public ...