• iOS 非ARC基本内存管理系列 2-多对象内存管理(1)


    单个对象的内存管理非常简单无非就是alloc对应release,retain对应release。但是如果涉及到很多对象,而且对象与对象有联系的时候该怎么去管理对象的内存呢。

    比如同样一本书有好3个人购买,那意味着3个人都在引用这本书。在内存中如图所示:

    那么如果Person对象引用Book对象的话就必须给Book对象的引用计数+1,如果不再引用Book对象就要把Book对象中的引用计数减1。遵循"有加必有减"

    1.多对象内存管理原则分析

    • 只要还有人在使用某个对象,那么这个对象就不会被回收
    • 只要你想用这个对象,就让对象的计数器+1
    • 当你不再使用这个对象时,就让对象的计数器-1
    • 只要有人在使用书,那书就不会释放

    2.谁创建谁release

    如果通过alloc、new或[mutable]copy来创建一个对象,那么必须调用release或autorelease

    换句话说,不是你创建的,就不用你去[auto]release

    3.谁retain谁release

    只要你调用了retain,无论这个对象是如何生成的,你都要调用release

    4.总结原则

    • 有始有终,有加就有减
    • 曾经让对象的计数器+1,就必须在最后让对象计数器-1

    5.代码实现

    /*
         
     需求:有连个类Person类和Book类,实现让Person类获取到Book,也就是人要获取书;
          如果Person类对象释放那么Book类对象也必须释放,也就是说一旦人没了,书也就没了
     
     设计类:既然人要占有书,那么可以在人中包含一个书类型,然后让实际的书给人中的书赋值那么人就拥有书了
     
    */

    内存结构如图:

     

    代码实现:

    /********************************** Person.h文件 *********************************/
    
    #import "Book.h"
    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    {
        // 既然人要拥又书,那么在Person类定义一个Book类型的成员变量 _book
        Book *_book;
    }
    
    // @property会隐藏底层内存管理 因此先不使用@property便于查看底层实现
    // @property Book *book;
    
    
    // 通过set方法为Person中的_book传入实际的book
    - (void)setBook:(Book *)book;
    
    - (Book *)book;
    
    @end
    
    
    
    
    /********************************** Person.m文件 *********************************/
    
    #import "Person.h"
    
    @implementation Person
    
    // 为Person中的_book传入Book对象 类似于给了Person中的_book给了一本书
    - (void)setBook:(Book *)book
    {
        // 既然人已经拥有了书 那么书的引用计数必须+1 因此调用书的retain方法
        _book = [book retain];
        NSLog(@"人拥有书了");
    }
    
    
    - (Book *)book
    {
        return _book;
    }
    
    // Person类对象在回收前调用方法
    - (void)dealloc
    {
        [_book release];
        NSLog(@"Person对象被回收");
        
        [super dealloc];
    }
    
    @end
    
    
    /********************************** Book.h文件 *********************************/
    
    #import <Foundation/Foundation.h>
    
    @interface Book : NSObject
    @end
    
    
    /********************************** Book.m文件 *********************************/
    
    #import "Book.h"
    
    @implementation Book
    
    // Book类对象在回收前调用方法
    - (void)dealloc
    {
        NSLog(@"Book对象被回收");
        
        [super dealloc];
    }
    
    @end
    
    /********************************** main文件 *************************************/
    
    #import <Foundation/Foundation.h>
    #import "Book.h"
    #import "Person.h"
    
    int main(int argc, const char * argv[])
    {
        Person *p = [[Person alloc] init];
        
        Book *b = [[Book alloc] init];
        
        // 为Person类对象中的_book传入实际的Book对象
        [p setBook:b];
        
        // 释放Person类对象
        [p release];
        
        // 既然Person类对象已经释放那么清除掉指向Person类对象的指针
        p = nil;
        
        // 既然Person类已经不可用了那么Book类对象也应该释放
        [b release];
        
        // 清空指向Book类对象的指针
        b = nil;
        
        return 0;
    }
  • 相关阅读:
    js获取input file完整路径的方法
    form提交表单上传图片
    基于HTML5的可预览多图片Ajax上传
    ie11兼容
    上传时获取文件的完整路径图片预览的js代码(兼容Firfox和IE)
    学习笔记
    ie浏览器兼容性(ie9,ie10)
    大学最后悔的事
    easyui 分页
    jQuery学习
  • 原文地址:https://www.cnblogs.com/QM80/p/3590865.html
Copyright © 2020-2023  润新知