九、oc中多对象内存管理基础学习

  

------- <a href="http://www.itheima.com" target="blank">Windows Phone 7手机开发</a>、<a href="http://www.itheima.com" target="blank">.Ios培训</a>、期待与您交流! -------

       内管管理是oc学习中,十分重要的一章节,是重点,也是难点。但自从苹果启用了ARC机制后,使用xcode编写oc程序,基本上不需要开发者们关注内存是否被收回,因为系统自动会帮助你回收,就像老师上课视频里说的,开起ARC后,代码你怎么写都是对的。那么对于我们初学者来说,要初步的掌握ARC机制,就需要把苹果的ARC机制关闭再进行学习。需要注意一点的是,oc中的ARC机制,并不等同于Java中的垃圾回收,Java中的垃圾回收,是运行时的特性。而oc中的ARC机制,不是运行时特性,它是编译器特性,编译器特性是指当编译器发现代码中有alloc、retain、copy后,系统会在相应位置自动加上release操作。

     首先,我们的得知道如何关闭ARC机制,新版的xcode与老版本的关闭,操作上有所不同。不仅仅如此,打开ARC后我们还需要打开僵尸对象检测功能,僵尸对象是指,当对象的内部引用计数器已经被清零了,那么这个对象的内存空间会被回收,那么这个对象就叫做僵死对象,如果一个对象已经成为僵死对象了,开发者再用指针去指向或者操作这个对象,编译器就会报野指针错误,指出该指针指向了一块坏的或者是不可用的内存区域。

     关闭ARC以及打开僵死对象检测的步骤:

     


    

    通过这三个步骤,我们为接下来内存管理的基础学习建立了基本的环境。

   多对象内存管理的代码演示:

       


   main函数:

#import <Foundation/Foundation.h>
#import "Boss.h"
#import "Macbook.h"
#import "Plane.h"
int main()
{
    Boss *b = [[Boss alloc] init]; // 有alloc,后面必有release,alloc操作使对b对象计数器加1,b = 1
    b.age = 45;
    
    Macbook *m = [[Macbook alloc] init]; // 有alloc,后面必有release,alloc操作使m对象计数器加1,m = 1
    b.macbook = m; // setter方法中,使m的计数器加1,m = 2

    Plane *p = [[Plane alloc] init]; // 有alloc,后面必有release,alloc操作使p对象计数器加1,p = 1
    b.plane = p; // setter方法中,使p的计数器加1,p = 2
    
    [p release]; // 调用release方法,使p的计数器减1,p = 1
    NSLog(@"%ld",[p retainCount]); // retainCounter方法,返回的是NSUInteger类型,也就是长整型
    
    [m release]; // 调用release方法,使m的计数器减1,m = 1
    NSLog(@"%ld",[m retainCount]); // retainCounter方法,返回的是NSUInteger类型,也就是长整型
    
    [b release]; // b = 0,b对象被回收,调用Boss类中的dealloc方法,使得p与m计数器也清零,对象也被回收
    
    return 0;
}
 

   Boss类的声明与实现:

#import <Foundation/Foundation.h>
#import "Macbook.h"
#import "Plane.h"

@interface Boss : NSObject
{
    int _age; // Boss的年龄,属于基本数据类型,不需要内存管理代码
    Macbook *_macbook; // Boss拥有的macbook对象,属于oc对象,需要内存管理代码
    Plane *_plane; // Boss拥有的Plane对象,属于oc对象,需要内存管理代码

}
// setter与getter方法的声明

- (void)setAge:(int)age;
- (int)age;

- (void)setMacbook:(Macbook *)macbook;
- (Macbook *)macbook;

- (void)setPlane:(Plane *)plane;
- (Plane *)plane;

@end
#import "Boss.h"

@implementation Boss

- (void)setAge:(int)age
{
    _age = age;
   
}
- (int)age
{

    return _age;
}


- (void)setMacbook:(Macbook *)macbook
{
    if (_macbook != macbook) // 检测新传入的对象是否与之前的对象相同,这样可以避免重复赋值后,出现野指针错误
    {
        [_macbook release];
        _macbook = [macbook retain]; // retain方法,是对象方法,调用后返回对象本身,并且使该对象计数器加1
    }

}
- (Macbook *)macbook
{
    return _macbook;
}


- (void)setPlane:(Plane *)plane
{
    if (_plane != plane) // 检测新传入的对象是否与之前的对象相同,这样可以避免重复赋值后,出现野指针错误
    {
        [_plane release];
        _plane = [plane retain]; // retain方法,是对象方法,调用后返回对象本身,并且使该对象计数器加1

    }

}
- (Plane *)plane
{

    return _plane;
}


- (void)dealloc
{

    NSLog(@"年龄为%d的Boss对象被回收",[self age]); // 打印,用于检测对象被回收后,是否调用了dealloc方法
    [_macbook release]; // 将该类,即是Boss类拥有的对象全部释放一次,注意是对象,基本上数据类型不是对象
    [_plane release];
    [super dealloc]; // dealloc方法的最后必须调用父类的dealloc方法,初学者不必深究
}


@end

Macbook类的声明与实现:

#import <Foundation/Foundation.h>

@interface Macbook : NSObject

@end
#import "Macbook.h"

@implementation Macbook


- (void)dealloc
{
    NSLog(@"Macbook对象被回收");
    [super dealloc];
}

@end

Plane类的声明与实现:

#import <Foundation/Foundation.h>

@interface Plane : NSObject

@end
#import "Plane.h"

@implementation Plane

- (void)dealloc
{
    NSLog(@"Plane对象被回收");
    [super dealloc];
}

@end

 程序执行后的结果为:


 

   


       结合上面代码以及代码里面的注释,可以比较清楚的认识到多对象内存关的初步知识。总结为几句话:有始有终,有加就有减,曾经让对象计数器加1,就必须在最后让对象计数器减1。最后还得注意一点的是,dealloc方法是对象方法,但是一般情况下不要直接调用,而是对象内部计数器清零后,系统会自动调用dealloc方法,把对象内存回收,被回收掉的对象,不能再进行操作,包括retain以及retainCount操作。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值