Object-C 学习笔记(十)---内存管理MRC

原创 2013年12月04日 11:23:07

内存管理


MRC——手动管理内存

ARC——自动管理内存


MRC

OC采用“引用计数”(retainCount)方式管理对象占用的内存

1.      使用alloc为对象分配内存;使用dealloc释放对象所占用的内存。

2.      使用alloc、new或者copy构造对象是,对象的retainCount为1.

3.      调用对象的retain方法可以增加1 retainCount

4.      调用对象的release方法可以减少1 retainCount

5.      当对象的retainCount为0时,dealloc会自动调用,释放对象内存;否则分配的内存讲被一直占用。

6.      所有对象可以使用retainCount属性查看当前的计数器值。

 

 

例子:

NSString *dadyCar = [[NSStringalloc]initWithFormat:@”Car”];// dadyCar拥有对象所有权retainCount+1

NSString *mumCar = [dadyCar retain];// mumCar拥有对象所有权,retainCount+1

 

NSString *sonCar = [mumCar retain];// sonCar拥有对象所有权,retainCount+1

 

NSString * friendCar = sonCar;// friendCar不拥有对象的所有权,只是简单指向对象内存空间,retainCount不会发生变化

 

[dadyCar release];// retainCount-1

[mumCar release];// retainCount-1

[sonCar release];// retainCount-1

注意:

         如果所有拥有对象的引用都释放了对象的所有权(retainCount=0),那么friendCar就变成了“野指针”,因为对象已经不存在,不能再调用对象的资源。



@property(retain,nonatomic)Strdent

一个类中,如果这个类有属性声明retain或者copy的属性,那么我们需要再这个类的dealloc方法里面释放这个属性。

 

dealloc方法在对象引用计数为0是自动调用。

主要用于适当自身所占用的资源。永远不要手动调用dealloc,应由系统自动调用。

 

真正释放对象内存空间的方位为:dealloc

当一个对象引用计数变成1时,再调用release的时候,其release就会自动调用系统的dealloc方法去释放对象所占的空间。

 

一般在类中需要overwrite覆盖/重写/复写dealloc方法,进行属性控制。

-(void)dealloc//相当于C++的析构方法

{

         //释放子类的引用

         [super dealloc];//调用父类的dealloc,释放父类

}

 

内存释放原则一:

       对象分配内存,并应在使用后,调用release释放内存。

凡是出现retain alloc copy的地方,都应该出现release与之匹配调用。

 

内存释放原则二:

         内存无法确定释放时间是,可以使用autorelease向最近池注册。

         有池决定释放时间

         使用便利构造器获得的对象,都应该是autorelease的。

 

Autorelease://自动释放

——延时释放对象内存。

对于每一个Runloop, 系统会隐式创建一个Autoreleasepool,这样所有的release pool会构成一个象CallStack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的Autorelease pool会被销毁,这样这个pool里的每个Object会被release。

例子:除了大括号之后,会自动release

 

(1)     当创建的对象未来某个时候销毁是,可以使用对象的autorelease。

(2)     对象讲所有管理权交给最近的NSautoreleasePool对象,并由其全权释放。

 

Autoreleasepool://自动释放池

         对象使用autorelease释放的会放进Autoreleasepool,系统自动释放。


例子:

//
//  People.h
//  Memory
//
//  Created by 5016 on 13-12-4.
//  Copyright (c) 2013年 dradon. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface People : NSObject

//成员属性
@property(retain,nonatomic)NSString* name;
@property(assign,nonatomic)NSInteger age;

-(People *)initWithName:(NSString*) name andAge:(NSInteger) age;

+(People *)PeopleWithName:(NSString*) name andAge:(NSInteger) age;

-(void)toString;


@end

//
//  People.m
//  Memory
//
//  Created by 5016 on 13-12-4.
//  Copyright (c) 2013年 dradon. All rights reserved.
//

#import "People.h"

@implementation People

@synthesize name=_name,age=_age;

-(People *)initWithName:(NSString*) name andAge:(NSInteger) age
{
    if(self = [super init])
    {
        _name = name;
        _age = age;
    }
    return self;
}

//便利构造器
+(People *)PeopleWithName:(NSString*) name andAge:(NSInteger) age
{
    People *person = [[People alloc] initWithName:name andAge:age];
    
    return [person autorelease];//向自动释放池注册
}


-(void)toString
{
    NSLog(@"我的名字是%@,今年%ld岁.",_name,_age);
}

//重写(overwirte)父类方法
-(void)dealloc//用来释放对象的方法,相当于C++里面的析构方法
{
    NSLog(@"这个对象被完全释放");
    self.name = nil;//等价于[_name release]或者[self.name release];
    [super dealloc];
}

@end

//
//  main.m
//  Memory
//
//  Created by 5016 on 13-12-4.
//  Copyright (c) 2013年 dradon. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "People.h"

int main(int argc, const char * argv[])
{
     NSLog(@"|-----------使用alloc开辟对象堆内存空间按-----------------|");
    People *person1 = [[People alloc]initWithName:@"DRAGON" andAge:23];//alloc开辟对象 +1
    [person1 toString];
    NSLog(@"person1的引用计数是:%ld",[person1 retainCount]);
    [person1 retain];//+1 = 2
    NSLog(@"person1的引用计数是:%ld",[person1 retainCount]);
    [person1 release];//-1 = 1 ;这里对象已经释放一次,引用计数为1
     NSLog(@"person1的引用计数是:%ld",[person1 retainCount]);
    [person1 release];//-1 = 0 ;这里对象再释放一次,引用计数为1-1,系统自动调用dealloc
    NSLog(@"person1的引用计数是:%ld",[person1 retainCount]);
    //[person1 release];//再调用一次,则是过度释放,会出现异常
    
    NSLog(@"|-----------使用便利构造器-----------------|");
    @autoreleasepool {//使用自动释放池进行释放,因为程序结束后会释放
        People *person = [People PeopleWithName:@"dragon" andAge:20];
        [person toString];//使用便利构造器 不需要使用release
    }

    return 0;
}

运行结果:



相信到了这里大家会基本理解内存管理.


相关文章推荐

object-c 内存管理学习笔记

NSAutoreleasePool *pool =[[NSAutoreleasePool alloc] init]; [pool drain]:这个函数可以把autoreleasePool里的对...

Object-c基础编程学习笔记-内存管理

- (id) retain; - (void) release; - (unsigned) retainCount;
  • cjfire
  • cjfire
  • 2014年08月30日 12:30
  • 587

OBject-C 学习笔记之内存管理

OBject-C 学习笔记之内存管理 基本原理:     1、内存管理         1.1移动设备的内存极其有限,每个app所能占用的内存是有限制的         1.2当app...

《Object-C编程全解》笔记二:基于引用计数的内存管理

基于引用计数的内存管理

《Object-C高级编程 iOS与OS X多线程和内存管理》读书笔记之一

第1章 自动引用计数 1.自动引用计数(ARC,Automatic Reference Coounting)是指内存管理中对引用采取自动计数的技术。 2.满足以下条件,就无需手工输入retain ...
  • xjh093
  • xjh093
  • 2016年12月09日 22:22
  • 343

ios学习--Object-C中的内存管理

免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播。同时,转载时不要移除本申明。如产生任何纠纷,均与本博客所有人、发表该翻译稿之人无任何关系。谢谢合作...

object-c学习之内存管理机制

版权声明 此文版权归作者VinceYuan (vince.yuan#gmail.com)所有。欢迎非营利性转载,转载时必须包含原始链接http://vinceyuan.cnblogs.com/,...

【Object - c 高级】01 内存管理 MRC

说道OC语言比较难理解比较绕弯弯的地方可能也就是内存管理这一块了, 正好复习到这里 就记录一下OC中的内存管理,如果您有幸看到此篇文章,请把我的不足之处指出谢谢! 一 内存区域的划分 内存...
  • ESCIC
  • ESCIC
  • 2016年11月04日 08:16
  • 145

OC_浅谈Object-C的内存管理机制

和C++一样通过内存操作获得的空间在使用完毕后需要释放内存否则就会造成内存泄露,接下来就让我们一起看看OC的内存管理机制; 首先我们知道oc的内存管理分为两部分:1、自动内存管理。2、手动内存管理。好...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Object-C 学习笔记(十)---内存管理MRC
举报原因:
原因补充:

(最多只允许输入30个字)