之前一片文章中我们介绍了OC中的两个关键字@property和@synthesize的使用的使用:

http://blog.csdn.net/jiangwei0910410003/article/details/41925967

今天我们来看一下OC中数组对象在是如何处理对象元素的引用计数问题的,同时介绍一下自动释放池的相关概念

一、数组对象是如何处理对象元素的引用计数问题

//
// main.m
// 26_NSArrayMemeryManager
//
// Created by jiangwei on 14-10-12.
// Copyright (c) 2014年 jiangwei. All rights reserved.
// #import <Foundation/Foundation.h> #import "Dog.h" int main(int argc, const char * argv[]) { Dog *dog1 = [[Dog alloc] init];
Dog *dog2 = [[Dog alloc] init]; NSMutableArray *array = [[NSMutableArray alloc] init]; //数组会对每一个元素retain
[array addObject:dog1]; //dog1计数=2
[array addObject:dog2]; //dog2计数=2 [dog1 release];
[dog2 release]; //当数组销毁的时候,会将所有的元素release
[array release];//数组销毁 //当数组移除所有的元素的时候,会讲所有的元素release
[array removeAllObjects]; return 0;
}

我们定义了Dog类,然后定义了NSMutableArray数组存放两个Dog对象,OC中在将对象放到数组中的时候,会自动调用retain方法,当数组对象本身被销毁的时候,会调用所有元素的release方法,当移除数组中所有的元素的时候,会调用元素的release方法

二、自动释放池的概念

//
// main.m
// 27_AutoReleasePool
//
// Created by jiangwei on 14-10-13.
// Copyright (c) 2014年 jiangwei. All rights reserved.
// #import <Foundation/Foundation.h> #import "Dog.h" int main(int argc, const char * argv[]) { /*
//创建一个自动释放池
//有作用域的问题,在{}中定义的东西外部是不能访问的,这点和NSAutoreleasePool有区别的
@autoreleasepool {//等价于[[NSAutoreleasePool alloc] init] Dog *dog2 = [[Dog alloc] init];
[dog2 retain]; }//等价于[pool release] //创建一个自动释放池
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; Dog *dog1 = [[Dog alloc] init];//计数:1 //将dog1对象加入到自动释放池中,却别于之前的release方法
//加入到自动释放池中之后,不是代表我们不需要管理引用了,只是自动释放池自动会调用一次release
//当自动释放池销毁的时候,释放池会对池中每一个对象调用一次release
[dog1 autorelease];
NSLog(@"dog1计数:%ld",dog1.retainCount); //销毁自动释放池
//这时候会调用dog1的release方法,dog1对象就被销毁了
[pool release];
*/ //自动释放池的嵌套
NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init]; //添加我们的代码
//dog1放到了pool1中
Dog *dog1 = [[Dog alloc] init];
[dog1 autorelease]; //自动释放池的嵌套
NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init]; //dog2放到了pool2中
Dog *dog2 = [[Dog alloc] init];
[dog2 autorelease]; //pool2销毁了
[pool2 autorelease]; //pool1销毁了
[pool1 release]; //下面的代码就是有问题的
//[person setDog:[[Dog alloc] init];
//正确的写法
//Dog *dogs = [[[Dog alloc] init] autorelease]; return 0;
}

我们在之前的文章中,定义一个对象的时候都会产生一个自动释放池,然后在释放池中编写我们的代码,自动释放池是系统提供的一种帮助我们去管理对象的引用计数问题。但是有时候代码必须在{...}中编写,这样的话就会产生作用域的问题,就是在{...}中定义的变量,在{...}外面不能使用。所以OC中就有了另外的一种方式:NSAutoreleasePool这个类

这种自动释放池可以实现嵌套

NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init];

//write code...

//pool1销毁了

[pool1 release];

上面的代码就相当于建立了一个自动释放池pool1,但是在这个中间的代码,如果要加入到这个池中,必须调用autorelease方法:

//dog1放到了pool1中
Dog *dog1 = [[Dog alloc] init];
[dog1 autorelease];

而且,这样定义一个池子还可以嵌套使用,直接看上面的例子代码,这样这个自动释放池我们就可以控制了。比系统提供的自动释放池可操作的地方很多

下面就直接对比一下:

NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init];

这行代码就相当于系统自动释放池的 {

[pool1 release];

这行代码就相当于系统自动释放池的 }

这样就好理解了吧

总结

这一篇文章主要介绍了OC中数组对象操作元素对象的时候需要处理的引用问题,以及我们可以自定义一个自动释放池,这种方式比系统提供的自动释放池方便,可操作性强。

OC学习篇之---数组对象的引用计数问题和自动释放池的概念的更多相关文章

  1. OC_内存管理(二)对象复制、循环引用问题、自动释放池

      循环调用: 1.循环引用的问题 两个对象A.B,有可能会出现特殊情况:A中包含B的实例变量:B中也包含A的实例变量,如果这两个实例变量都是强引用(A有着B的实例变量所有权,B也有A的实例变量所有权 ...

  2. OC学习篇之---总结和学习目录

    今天终于把OC的基础知识学习完了,但是这些知识只是最基础的,还有很多高级知识,这个可能需要后面慢慢的去学习才能体会到.下面就是这次学习OC的目录教程,如果大家发现有什么不正确的地方,请指正,小弟是新生 ...

  3. OC学习篇之---循环引用问题

    在之前的一片文章中,我们介绍了数组操作对象的时候引用问题以及自动释放池的概念: http://blog.csdn.net/jiangwei0910410003/article/details/4192 ...

  4. (转载)OC学习篇之---第一个程序HelloWorld

    之前的一片文章简单的介绍了OC的相关概述,从这篇开始我们就开始学习OC的相关知识了,在学习之前,个人感觉需要了解的其他的两门语言:一个是C/C++,一个是面向对象的语言(当然C++就是面向对象,不过这 ...

  5. OC中对象元素的引用计数 自动释放池的相关概念

    OC中数组对象在是如何处理对象元素的引用计数问题的,同时介绍一下自动释放池的相关概念 一.数组对象是如何处理对象元素的引用计数问题[objc]  view plaincopy 1. //   2. / ...

  6. OC学习篇之---第一个程序HelloWorld

    从这篇开始我们就开始学习OC的相关知识了,在学习之前,个人感觉需要了解的其他的两门语言:一个是C/C++,一个是面向对象的语言(当然C++就是面向对象,不过这里最好还是Java).在干活之前,得先找到 ...

  7. OC学习篇之---单例模式

    在之前的一片文章中介绍了对象的拷贝相关知识:http://blog.csdn.net/jiangwei0910410003/article/details/41926531,今天我们来看一下OC中的单 ...

  8. OC学习5——类和对象

    1.OC是在C语言基础上进行扩展得到的一门面向对象的程序设计语言,它也提供了定义类.成员变量和方法的基本功能.类可以被认为是一种自定义的数据类型,使用它可以定义变量,所有使用类定义的变量都是指针类型的 ...

  9. OC学习篇之---内存管理介绍和使用

    在之前的一片文章我们说了OC中谓词操作:http://blog.csdn.net/jiangwei0910410003/article/details/41923507,从今天开始我们就来看一下OC中 ...

随机推荐

  1. JS中的作用域及闭包

    1.JS中的作用域 在 es6 出现之前JS中只有全局作用域和函数作用域,没有块级作用域,即 JS 在函数体内有自己的作用域,但是如果不是在函数体的话就全部都是全局作用域.比如在 if.for 等有 ...

  2. Codeforces 803F - Coprime Subsequences(数论)

    原题链接:http://codeforces.com/contest/803/problem/F 题意:若gcd(a1, a2, a3,...,an)=1则认为这n个数是互质的.求集合a中,元素互质的 ...

  3. 洛谷 4099 [HEOI2013]SAO——树形DP

    题目:https://www.luogu.org/problemnew/show/P4099 结果还是看了题解才会…… 关键是状态,f[ i ][ j ] 表示 i 子树. i 号点是第 j 个出现的 ...

  4. 使用SSH 工具 Xshell 6连接CentOS 7.4

    在使用Xshell 6连接 服务CentOS 7.4之前,首先你要配置好服务器,如果没有配置好服务器的,请访问: (一)小白教小白配置 服务器 好了,开始正文! 首先准备,SSH 工具 Xshell ...

  5. 使用ajax前必须了解的知识

    ajax的全称: asynchronous javascript and xml (异步的javascript和xml) ajax不是某种编程语言 是一种在无需重新加载整个页面的情况下能够更新部分网页 ...

  6. Docker容器数据卷-Volume详解

    Docker中的数据可以存储在类似于虚拟机磁盘的介质中,在Docker中称为数据卷(Data Volume).数据卷可以用来存储Docker应用的数据,也可以用来在Docker容器间进行数据共享.数据 ...

  7. WEB服务端安全---注入攻击

    注入攻击是web领域最为常见的攻击方式,其本质是把用户输入的数据当做代码执行,主要原因是违背了数据与代码分离原则,其发生的两个条件:用户可以控制数据输入:代码拼接了用户输入的数据,把数据当做代码执行了 ...

  8. 【读书笔记】:MIT线性代数(5):Four fundamental subspaces

    At the beginning, the difference between rank and dimension: rank is a property for matrix, while di ...

  9. JAVA中的面向对象与内存解析_1

    对象的创建和引用   必须使用new关键字创建对象. 使用对象(引用成员变量或来引用对象的成员变量. 使用对象(引用)方法(参数列表)来调用对象的方法. 同一类的每个对象有不同的成员变量存储空间. 同 ...

  10. log4j/slf4j

    log4j的使用 引入log4j.jar包 <dependency> <groupId>log4j</groupId> <artifactId>log4 ...