美文网首页与时俱进的IT
OC(七)内存管理

OC(七)内存管理

作者: 社会主义顶梁鹿 | 来源:发表于2018-07-29 16:44 被阅读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;

    }

    相关文章

      网友评论

        本文标题:OC(七)内存管理

        本文链接:https://www.haomeiwen.com/subject/zyxtvftx.html