内存管理

  1、基本知识

  2、关闭ARC机制

  3、@property

  4、循环引用

  5、自动释放池

  6、内存管理总结

一、基本知识

内存的分类

  栈:局部变量

  堆:动态申请的对象,变量等

  全局(静态):static 变量,const变量,全局变量等

引用计数器

   每个OC对象都有自己的引用计数器,是一个整数,表示“对象被引用的次数”,即有多少人正在使用这个OC对象

  每个OC对象内部专门有4个字节的存储空间来存储引用计数器

 作用

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

  当一个对象的引用计数器值为0时,对象占用的内存就会被系统回收。换句话说,如果对象的计数器不为0,那么在整个程序运行过程,

它占用的内存就不可能被回收,除非整个程序已经退出。

引用计数器的操作

  1、给对象发送一条retain消息,可以使引用计数器值+1(retain方法返回对象本身)

  2、给对象发送一条release消息,可以使引用计数器值-1

  3、可以给对象发送retainCount消息获得当前的引用计数器值

总结:有始有终,有加有减。

二、关闭ARC机制

如果要自己调用release等函数,需要关闭ARC功能,关闭方法参考

http://jingyan.baidu.com/article/358570f67babbcce4724fcd8.html

管理方式set方法加1,dealloc 减1

1、想使用某个对象,就应该让对象的计数器加1(retain)

2、不想再使用某个对象时,就应该让对象的计数器减1 (release)

2、谁retain谁release,谁alloc谁release

内存管理规范:

1、只要调用alloc必须有release,如果不是alloc那就不需要release

2、set 方法

  基本数据类型直接赋值

  OC对象类型。

  先判断是不是同一个对象 if(car != _car)。

  然后对旧对象release,对新车进行一次retain操作。

3、dealloc

  一定要调用[super dealloc],而且放到最后边

  一定要当前对象release一次

 三、@property 

@property  // 默认是赋值,retain 参数实现内存管理

@property int age; // 默认是赋值
@property(retain) Book * book; // retain 参数实现内存管理

内存管理总结:

1、内存管理的相关参数

  retain  :release旧值,retain新值

  assign  :直接赋值,默认就是这个,适用于非OC对象类型

  copy   :release旧值,copy新值

  retain是指针拷贝,copy是内容拷贝。

2、是否要生成set方法

  @property (readonly) int age; // 只读,只生成getter方法

  @property (readwrite) int name; // 读写,默认是读写

3、多线程管理

  nonautomic   : 性能高,

  automic     : 性能低(默认)

  @property  (nonautomic , assign) int age; // 以后这样写,默认的assign也要写出来,这样比较明显

4、setter和getter方法的名称

  @property  (setter = myAge:) int age; // setter = set方法名 ,自定义setter方法名,不要忘记冒号

  @property  (getter = getAge) int age; // getter = get方法名 ,自定义getter方法名

  @property  (getter = isRich) BOOL rich; // 一般这个会用在BOOL类型的变量声明,getter方法名以is开头

四、循环引用

类A引用类B,类B引用类A。

解决方法:  @class A;//  仅仅告诉编译器A是一个类

在类引用前,在声明文件里使用关键字@class A;

@class 和#import区别

  1、#import方式会包含被引用类的所有信息,包括被引用类的变量和方法;@class方式只是告诉编译器在A.h文件中 B *b 只是类的声明,具体这个类里有什么信息,这里不需要知道,等实现文件中真正要用到时,才会真正去查看B类中信息

  2、如果有上百个头文件都#import了同一个文件,或者这些文件依次被#improt,那么一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍,这样的效率也是可想而知的,而相对来 讲,使用@class方式就不会出现这种问题了

  3、在.m实现文件中,如果需要引用到被引用类的实体变量或者方法时,还需要使用#import方式引入被引用类

代码示例

 #import <Foundation/Foundation.h>
@class Card; // 引用类声明
@interface Person : NSObject @property (nonatomic, retain) Card *card; @end
 #import "Person.h"
#import "Card.h" // 包含头文件
@implementation Person - (void)dealloc
{
//[_card release];
NSLog(@"card dealloc");
[super dealloc];
}
@end
 #import <Foundation/Foundation.h>
@class Person; // 引用类声明 @interface Card : NSObject @property (nonatomic, retain) Person *person; @end
 #import "Card.h"
#import "Person.h" // 引用头文件
@implementation Card
- (void)dealloc
{
[_person release];
NSLog(@"person dealloc");
[super dealloc];
}
@end

main函数

  int main()
{
Person *p = [[Person alloc] init];
Card *c = [[Card alloc] init];
// 这里就回出现循环retain现象,下面会解释解决方法
p.card = c;
c.person = p; // 实际上,这两个对象都没释放
[p release];
[c release];
return ;
}

针对上面的问题,这里给出一个解决方法,如下:

 #import <Foundation/Foundation.h>
@class Person; // 引用类声明 @interface Card : NSObject // 避免循环retain导致对象不能正确释放,可以把其中一个的声明写为assign,这样就可以正常释放,这是一个特例
@property (nonatomic, assign) Person *person; @end

在开发中引用一个类的规范

 1、在.h文件中用@class来声明类

 2、 在.m文件中用#import 来包含类的所有东西

 3、 循环retain的解决方案

   一端用retain,一端用assign

五、自动释放池

autorelease 基本用法

  1、会将对象放到一个自动释放池中

  2、当对象释放池被销毁时,会自动释放里面的所有对象(release操作)

  3、会返回对象自身

  4、调用autorelease后,对象的计数器不变

好处

  1、不用再关心对象释放的时间

  2、不用再关心什么时候调用release

注意事项

  1、占用内存较大的对象不要随便使用autorelease

  2、占用内存较小的使用autorelease,没有太大影响

  3、autorelease和release一样,也是和alloc/new/copy一一对应

  4、自动释放池是以栈结构存储在内存中的,当调用一个autorelease时,会将对象放到栈顶

  5、系统自带的方法里面没有含有alloc、new、copy,说明返回的对象都是autorelease类型的

  6、开发中常常会提供一个快速生成一个返回autorelease类型的类方法

    创建对象不要直接用类名,要用self,这样子类调用也不会出错

  7、

 @autoreleasepool // 自动释放池
{
Person *p = [[[Person alloc] init] autorelease]; // autorelaese 方法返回对象本身,计数器并不会立即改变
Card *c = [[[Card alloc] init] autorelease]; p.card = c;
c.person = p; @autoreleasepool // 可以嵌套
{ Person *p = [[[Person alloc] init] autorelease];
Card *c = [[[Card alloc] init] autorelease]; p.card = c;
c.person = p; } }

 autorelease优化

写一个类方法将autorelease封装起来

 // 类方法,返回对象自身,将autorelease封装起来
+ (id)person
{
return [[[Person alloc] init] autorelease]; // 直接返回对象
}

使用起来很方便

  Person *p = [Person person];

字符串  默认就是autorelease

NSString *str = @"dsfgsdfg"; // 默认就是autorelease

内存管理总结

  计数器基本操作

    retain +1

    release -1

    retainCount 获得计数器

  set方法的内存管理

    - (void)setCar:(Car *)car

    {

      if(car != _car)

      {

        [_car relaease];

        _car = [car retain];  

      }

    }

  @property参数

    OC对象类型

    @property (nonatomic, retain) 类名 *属性名;

    @property (nonatomic, tetain) Car *car;

    retain过一定要在dealloc里进行release

    非OC类型那个

    @property (nonatomic, assign) 类型名 属性名;

    @property (nonatomic, assign) int age;

   autorelease

    系统自带的方法中,如果不包含alloc、new、copy,那么这些方法返回的都是autorelease过的

    开发中常常会提供一个快速生成一个返回autorelease的对象,创建对象不要直接用类名,要用self,这样子类调用也不会出错

2015-04-18 今日如此,明日依旧。

IOS开发学习笔记013-内存管理的更多相关文章

  1. linux kernel学习笔记-5内存管理_转

    void * kmalloc(size_t size, gfp_t gfp_mask); kmalloc()第一个参数是要分配的块的大小,第一个参数为分配标志,用于控制kmalloc()的行为. km ...

  2. XV6学习笔记(2) :内存管理

    XV6学习笔记(2) :内存管理 在学习笔记1中,完成了对于pc启动和加载的过程.目前已经可以开始在c语言代码中运行了,而当前已经开启了分页模式,不过是两个4mb的大的内存页,而没有开启小的内存页.接 ...

  3. ios学习笔记之内存管理

    一,内存管理类型定义      1,基本类型  任何C的类型,eg:      int,short,char,long,long long,struct,enum,union等属于基本类型或结构体   ...

  4. iOS开发学习笔记:基础篇

    iOS开发需要一台Mac电脑.Xcode以及iOS SDK.因为苹果设备都具有自己封闭的环境,所以iOS程序的开发必须在Mac设备上完成(当然,黑苹果应该也是可以的,但就需要花很多的精力去折腾基础环境 ...

  5. iOS开发学习笔记

    1 常用的第三方工具 1.1 iPhone Simulator 测试程序需要模拟器iPhone Simulator 1.2 设计界面需要Interface Builder,Interface Buil ...

  6. ios开发学习笔记(1)

    objective-c基础总结 第一二章 1.application:didiFinishLauchingWithOptions:程序启动后立即执行 2.启动界面代码格式:self.window = ...

  7. iOS开发系列—Objective-C之内存管理

    概述 我们知道在程序运行过程中要创建大量的对象,和其他高级语言类似,在ObjC中对象时存储在堆中的,系统并不会自动释放堆中的内存(注意基本类型是由系统自己管理的,放在栈上).如果一个对象创建并使用后没 ...

  8. IOS开发学习笔记014-ARC机制

    ARC 1.ARC机制 2.ARC 判断准则 3.注意事项 4.ARC和非ARC混合使用 ARC机制 ARC 是编译器特性,而不是 iOS 运行时特性,它也不是类似于其它语言中的垃圾收集器.因此 AR ...

  9. COCOS学习笔记--Cocod2dx内存管理(三)-Coco2d-x内存执行原理

    通过上两篇博客.我们对Cocos引用计数和Ref类.PoolManager类以及AutoreleasePool类已有所了解,那么接下来就通过举栗子来进一步看看Coco2d-x内存执行原理是如何的. / ...

随机推荐

  1. Android 使用GreenDao 添加字段,删除表,新增表操作

    GreenDao 给我个人感觉 比一般的ORM框架要好很多,虽然说上手和其他的比起来,较复杂,但是如果使用熟练以后,你会爱上这个框架的 用这些ORM 框架给我的感觉都是,当升级时,都需要进行数据库所有 ...

  2. mysql decimal类型与decimal长度用法详解

    三者的区别介绍 float:浮点型,含字节数为4,32bit,数值范围为-3.4E38~3.4E38(7个有效位) double:双精度实型,含字节数为8,64bit数值范围-1.7E308~1.7E ...

  3. Visual Studio 2017 如何打开Model Browser(实体数据模型浏览器)

    写一个笔记,记录下在Visual Studio 2017中打开EF模型浏览器的步骤和方法,方便以后忘记了可以重新查阅.主要是现在VS功能越来越多,很多功能模块/界面要开启都是有先决条件,总之隐藏的很深 ...

  4. python3应用例子01(进度条)

    #!/usr/bin/env python# -*- coding:utf-8 -*- import sysimport time def bar(num, total): rate = num / ...

  5. ubuntu16.04解决屏幕适应问题

    打开ubuntu登录进去后,输入: sudo  apt-get installopen-vm-tools sudo apt-get install open-vm* 然后重启(reboot),即可解决 ...

  6. HDU 1114 Piggy-Bank 猪仔储钱罐(完全背包)

    题意: 给定一个存钱罐中要存硬币,知道空罐的重量和欲装满的重量,是否能装入?若能,打印最小价值.(注:能装的硬币重量一定刚刚好,里面的总价值要达到最小) 输入: 包含了T个测试例子,在第一行给出.接下 ...

  7. 2018.7.2 如何用js实现点击图片切换为另一图片,再次点击恢复到原图片

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  8. python_57_高阶函数

    变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数. def add(a,b,f): return f(a)+f(b) res=add(-3,- ...

  9. python_29_三级菜单

    menu={ '北京':{ '海淀':{ '五道口':{ '搜狐':{}, '网易':{}, 'Google':{}, }, '中关村':{ '爱奇艺':{}, '汽车之家':{}, '优酷':{}, ...

  10. Framework7:不会Objective-C,也能开发iOS7应用

    摘要:Framework7是一款开源的轻量级HTML框架,用来创建混合或有着iOS7原生体验的Web应用.其包含HTML布局.所有基础界面.动画效果.视图以及简单的自定义样式,让你无需修炼Object ...