与时俱进的IT

OC(七)内存管理

2018-07-29  本文已影响0人  社会主义顶梁鹿

一.ios的app使用的内存超过30M,则系统会向改app发送Memory Warning消息,收到消息,他必须正确处理,负责可能出现内存泄露甚至崩溃。 

 对象是要占用内存的,如果创建了对象(分配了内存)而不去释放这些对象所占用的内存,将会发生内存泄露。

 需要手动去管理内存。

 管理内存:

 1.分配内存

 2.释放内存

 在不需要这个对象的时候,及时把这个对象释放掉,就可以防止内存泄露(只分配,不释放)。

 不知道怎么去判断是否需要释放一个对象

 引用计数:是判断一个对象是否存在的一个标准

 得到引用计数公式:对象名.retainCount

 什么样的数据需要咱们手动管理内存?

 基本数据类型(不能称之为对象,不具备对象的属性特征,只是一个单一的数据)不需要咱们手动管理内存,它由系统处理    ->栈

 除了基本数据类型,都需要手动管理内存(需要程序员管理) ->堆

 程序员开辟的内存,属于分配到堆里,系统自动分配的内存会到栈里。

person *p = [[person alloc]init]; 堆

int a = 10; 栈

 谁分配谁释放

retainCount 引用计数>0的时候,就是对象存在的时候,如果不大于0,就表示这个对象已经被释放了.    

 二. 生命周期

 1.alloc之后对象就存在了

 2.具体对对象的操作

 3.释放对象

 引用计数的操作:

 引用计数是判断一个对象是否存在的一个标准(>0)

 *******重要********

 让引用计数+1的方法:

 ①.alloc、new

 ②.retain 保留引用计数

 ③.copy

 让引用计数-1的方法:

 ①.release 释放

 ②.autorelease 延迟释放

 对象被释放的时候会调用一个销毁对象的方法--delloc->销毁对象

 有一个alloc、retain、copy就要有一个对应的release,才能释放掉对象。

 MRC:手动管理引用计数

 ARC:自动管理引用计数

 setter方法的内存管理

 - (void)dealloc{

 [super delloc];

 [原来的变量(全局变量) release];

 }

 - (void)set对象名:(类型)参数名{

 if (原来的变量 != 参数名){

 [原来的变量 release];

 原来的变量 = [参数名 retain];

 }

 }

 内存管理的原则:谁分配谁释放

 有一个alloc retain copy 就要有对应的release autorelease

 引用技数:retaincount

 引用计数+1:alloc retain copy

 引用计数-1:release autorelease

copy 会产生一个新的对象,新的对象引用计数+1,跟原来对象没有关系

 如果释放了原来的对象,新的对象依然存在

retain 保留引用计数,给原来对象引用计数+1,只要有一个引用计数为0,这个对象就会被销毁掉。

 autorelease:延迟释放 等到需要释放时才去释放,也会引用计数-1

 常与自动释放池配合使用 

 自动释放池:在自动释放池里面的对象,只要使用了outorelease 在出池的时候就会被统一释放掉

 自动释放池的两种写法:

 1、@autoreleasepool {

 花括号内表示在自动释放池内

 }出了花括号就表示出池(所有使用autorelease的对象全部会被释放掉)

 2、NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];

 只要在自动释放池对象release之前都算池内

 [pool release];

 属性的ARC关键字的声明

 属性手动管理引用计数:

 ARC:自动管理引用计数

 MRC:手动管理引用计数

//自动释放池的生命周期

 //当对象在自动释放池被创建,并使用auyorelease

 //对象会在自动释放池出池的时候,被自动释放池统一调用池内全部的autorelease 释放全部对象

 //可以使用在循环创建一些对象的时候,不知道什么时候创建使用完毕,可以选择使用自动释放池

 @autoreleasepool {

//        Person *laoWang = [[[Person alloc]init]autorelease];

 /*     Person *person = [[Person alloc]init];

//        Person *person = [Person new];

        [person retain];

//retain 给同一对象保留引用计数

        //目的 为了保证一个不会被释放掉,给这个对象引用计数+1

        Person *ppp = [person retain];

        NSLog(@"%ld",ppp.retainCount);

        [person release];

        NSLog(@"%ld",person.retainCount);

        //打印结果:内存管理[1263:49394] 2

        //打印结果:内存管理[1263:49394] 1

        [person release];

        //打印结果:对象已经被销毁

        //如果一个对象被释放掉 这个对象就是野指针(指针跟对象都存在着,但是联系不起来了),为了防止使用野指针可以在这个对象释放之后,同时给这个对象赋值为空(nil)

        person = nil;

        */

//        

//        Person *person = [[Person alloc]init];

//        Person *pp = [person retain];

//        [person release];

//        [pp release];

//        Weapon *qiang = [[Weapon alloc]init];

//        Person *huluiwa = [[Person alloc]init];

//        [huluiwa setWeapon:qiang];

//        [qiang release];

 //如果现在释放qiang  huluwa这个对象还在使用 就得想办法让qiang不被销毁

 //方法:+1,在setWeapon这个方法中

 //在dealloc方法中销毁qiang

//        NSLog(@"%@",huluiwa.weapon);

//        [huluiwa release];

//        NSArray *list = [[NSArray alloc]initWithObjects:@"1111", nil];

//        NSArray *list2 = [list copy];

//        //nil 存在的对象也可以置空

//        [list release],list = nil;

//        NSLog(@"%@",list2);

//        [list2 release];

 NSMutableArray *list = [NSMutableArray array];

 //作用域不放入自动释放池

 /*     @autoreleasepool {

            for (int i=0; i<10; i++) {

                Person *p = [[[Person alloc]init]autorelease];

                [list addObject:p];

            }

        }*/

 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];

 for (int i=0; i<10; i++) {

 Person *p = [[[Person alloc]init]autorelease];

[list addObject:p];

        }

[pool release];

------.h----------

{

 Weapon *_weapon;

}

-(void)setWeapon:(Weapon *)weapon;

-(Weapon *)weapon;

//在字符串、数组、字典、为属性的一般都是用copy

//其他对象都是使用retain

@property (nonatomic,copy)NSString*name;

//基本数据类型使用assign(直接赋值)

//属性其他关键字

//1.只读:readonly只允许访问 不允许修改(只允许使用getter方法)

//2.读写:readwrite

//3.getter=isSuccess 表示在赋值的时候,这个属性叫做success 在取值的时候叫做isSuccess

//1.retain:只要使用属性 除了基本数据类型 都可以使用retain

//2.copy:在字符串、数组、字典、为属性的一般都是用copy

//是为了防止赋值的数组被释放置空,影响属性的数组,生成一个新的数组

//3、assign 是直接赋值 只要是基本数据都是用assign

//设置属性的访问权限

//readwrite:开放属性的全部权限

//readonly:只开放读取的权限(保护对象里面的数据不被修改)

//ARC:

//1.strong强壮的 不会被释放调用<告诉系统这个属性是不能被释放的>

//2.unsafe_unretained 允许在特殊情况下释放掉,不安全的

-------------.m----------

//重写(父类方法子类再写一次)

//优先调用子类重写父类的方法

//如果子类还想实现父类同样的功能

- (void)dealloc

{

 //具体销毁对象的内容

 //当引用计数为0的时候会自动调用这个方法

 //当人被销毁的时候也就是不再需要武器的时候,就可以销毁

    [_weapon release],_weapon = nil;

 NSLog(@"对象已经被销毁");

    [super dealloc];

}

-(void)setWeapon:(Weapon *)weapon{

 //咱们可以确定 person这个对象什么时候被销毁

 //可以在销毁这个对象的同时销毁武器

 if (_weapon != weapon) {

 _weapon = [weapon retain];

    }

}

-(Weapon *)weapon{

 return _weapon;

}

上一篇下一篇

猜你喜欢

热点阅读