zoukankan      html  css  js  c++  java
  • Objective

    在前面, 我们知道了OC中内存管理的机制, 引用计数, 也对引用计数有了基本的认识, 有些人可能会说, 引用计数而已, 不就是+1, -1么, 有多难?  的确, 在单个对象中的操作的确不难, 但如果是在多个对象之间操作呢? 这个就难了, 为什么这么说? 下面我们来看看示意图:




    在示例图中, 有两个对象在调用Book, 那么Book的引用计数就为2, 每当释放一个对象Book的引用计数就-1, 其实这个关系到一些比较复杂的操作, 如果你释放了Student对象, 并没有把它的指针也清零, 那么Book这个对象就不会被释放, 一直存在于内存中, 当然, 只释放Person对象也是一样, 所以在我们需要思考更多的问题, 看看哪个对象没有被释放, 哪个对象的指针没有清零等等....





    前面我们也说过, 谁通过alloc,new, copy或者[mutable]copy等方法创建, 那么就必须得调用release, 或者autorelease去释放对象, 这里有几个方法我们暂时没讲, 先不去理会.




    还有一点就是谁retain, 那么就是谁release, 有始有终, 有增有减, 曾经让对象+1, 那么最后就必须让对象-1.



    来看看代码例子:

    <span style="font-size:12px;">#import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    {
        Book *_book;
    }
    - (void)setBook:(Book *)boook;
    - (Book *)book;
    
    @end
    
    @implementation Person
    - (void)setBook:(Book *)boook
    {
        _book = book;
    }
    - (Book *)book
    {
        return _book;
    }
    @end</span>

    <span style="font-size:12px;">#import <Foundation/Foundation.h>
    
    @interface Book : NSObject
    {
        int _price;
    }
    - (void)setPrice:(int)price;
    - (int)price;
    @end
    
    @implementation Book
    - (void)setPrice:(int)price
    {
        _price = price;
    }
    - (int)price
    {
        return _price
    }
    @end</span>

    #import <Foundation/Foundation.h>
    #import "Book.h"
    #import "Person.h"
    int main()
    {
        Book *b = [[Book alloc] init];
        Person *p = [[Person alloc]init];
    
    
        [b release];
        b = nil;
    
        [p release];
        p = nil;
        return 0;
    }


    经过我们这么一些, 那么首先消失的就是b这个对象, 并且它的指针也会清零, 那么Book这个对象就会被释放, 看上去貌似没问题, 其实问题大大滴, 下面我们看看释放后的示意图:



    PS: b指向Book对象的这根线是虚线, 代表的是已经被清零.


    按照例子来讲, 我们所画的示意图就是和例子一样的结果, Book对象是被释放了, 但在Person对象里面, 还有一个_book指向着Book对象, 在这样子的情况下, 合理吗? 答案肯定是否定的.


    那么我们应该怎么做呢?

    <span style="font-size:12px;">@implementation Person
    - (void)setBook:(Book *)boook
    {
    	_book = [book retain];
    }
    - (Book *)book
    {
    	return _book;
    }
    - (void)dealloc
    {
    	[_book release];
    	NSLog(@"对象被释放了");
    	[super dealloc];
    }
    @end</span>

    只有这样子, 才可以使得Book被释放的时候, _book还有效, 并且只有通过Person对象被释放, 才可以完全的把Book对象给释放.

    原理就是:



    这样子我们就遵循了内存管理的原则, 永远都不会有错, 而一当b对象不想拥有Book对象的时候, 那么就可以释放, 并且清空它的指针, 但Person对象还拥有Book, 所以Book对象的计数器是1, 这样子程序就不会产生内存泄漏.






    最后, p对象release了, 那么Book对象和Person对象的计数器都变为0, 全部对象被释放, 并且指针清零, 非常严禁的内存管理.







    好了, 这次我们就讲到这里, 下次我们继续~~

  • 相关阅读:
    [Go] Slices vs Array
    [置顶] SpecDD系列:“完成” 的定义
    关于游戏开发的一点随笔
    提高效率 常用的几个xcode快捷键
    关于android 自己实现 back键 home键
    (组合数学3.1.1.1)POJ 1146 ID Codes(字典序法)
    [置顶] c# asp.net 修改webconfig文件 配置
    python数据类型和3个重要函数
    jdk环境变量配置
    VM虚拟机下在LINUX上安装ORACLE 11G单实例数据库
  • 原文地址:https://www.cnblogs.com/iOSCain/p/4282827.html
Copyright © 2011-2022 走看看