1.@class

  • 使用场景:对于循环依赖关系来说,比方A类引用B类,同时B类也引用A类;

  可以看出Person和Card互相引用,此时如果使用#import编译报错!因此当使用@class在两个类中相互声明,编译不会报错!

  • 用法:使用 @class 类名; 就可以引用一个类,说明一下它是一个类

@class和#import的区别:

  • #import方式会包含被引用类的所有信息,包括被引用类的变量和方法;@class方式只是告诉编译器在A.h文件中 B *b 只是类的声明,具体这个类里有什么信息,这里不需要知道,等实现文件中真正要用到时,才会真正去查看B类中信息
  • 如果有上百个头文件都#import了同一个文件,或者这些文件依次被#improt,那么一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍,这样的效率也是可想而知的,而相对来 讲,使用@class方式就不会出现这种问题了
  • 在.m实现文件中,如果需要引用到被引用类的实体变量或者方法时,还需要使用#import方式引入被引用类

2.循环retain

  • 比如A对象retain了B对象,B对象retain了A对象
  • 这样会导致A对象和B对象永远无法释放

3.解决方法

当两端互相引用时,应该一端用retain、一端用assign 模拟代码如下:


/**

 需求:人拥有身份证,而身份证上显示人的信息,
设计:分别设计Person类和Card类模拟
注意:两个类循环引用因此设置Card一端为assign */

/********************************* Person.h *************************************/

#import <Foundation/Foundation.h>

@class Card;

@interface Person : NSObject

@property (nonatomic,retain) Card *card;

@end

/********************************* Person.m *************************************/

#import "Person.h"
#import "Card.h"
@implementation Person - (void)dealloc
{
[_card release]; NSLog(@"Person对象被回收了"); [super dealloc];
} @end /********************************* Card.h *************************************/ #import <Foundation/Foundation.h> @class Person; @interface Card : NSObject // 虽然Person是类对象 但为了解决互相retain的问题 将Car的这一端的person设置成为assign
@property (nonatomic,assign) Person *person; @end /********************************* Card.m *************************************/ #import "Card.h"
#import "Person.h"
@implementation Card - (void)dealloc
{
NSLog(@"Card对象被回收"); [super dealloc];
} @end /********************************* main.m *************************************/ #import <Foundation/Foundation.h>
#import "Person.h"
#import "Card.h"
int main(int argc, const char * argv[])
{
Person *person = [[Person alloc] init];
Card *card = [[Card alloc] init]; // 人拥有身份证
person.card = card; // 执行后card的引用计数 = 2 // 身份证上显示的人的信息 Car中person中assign person引用计数 = 1
card.person = person; // card计数-1
[card release]; // persong引用计数 = 0 person对象要被回收了 调用 person.dealloc 方法
[person release]; return ;
}

iOS 非ARC基本内存管理系列 3-循环retain和@class的更多相关文章

  1. iOS 非ARC基本内存管理系列 2-多对象内存管理(3) 利用@property来自动管理内存

    iOS 基本内存管理-多对象内存管理(2)中可以看到涉及到对象的引用都要手动管理内存:每个对象都需要写如下代码 // 1.对要传入的"新车"对象car和目前Person类对象所拥有 ...

  2. iOS 非ARC基本内存管理系列 -手把手教你ARC——iOS/Mac开发ARC入门和使用(转)

    手把手教你ARC——iOS/Mac开发ARC入门和使用 Revolution of Objective-c 本文部分实例取自iOS 5 Toturail一书中关于ARC的教程和公开内容,仅用于技术交流 ...

  3. iOS 非ARC基本内存管理系列总结6 -设计微博模型

    设计简单的微博模型:用User类和Status类来模拟实现 在非ARC机制下有两种方式,两者没有太大的区别之所以写了两种只是为了方便学习和对比两种写法! 第一种:没有使用atuorelease和自动释 ...

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

    /* 多对象内存管理: 以人拥有车为例涉及到@property底层set方法管理内存的实现 注意:人在换车的时候要进行当前传入的车和人所拥有的车进行判断 */ /******************* ...

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

    单个对象的内存管理非常简单无非就是alloc对应release,retain对应release.但是如果涉及到很多对象,而且对象与对象有联系的时候该怎么去管理对象的内存呢. 比如同样一本书有好3个人购 ...

  6. iOS 非ARC基本内存管理系列 1-引用计数器

    1.什么是内存管理 移动设备的内存极其有限,每个app所能占用的内存是有限制的 当app所占用的内存较多时,系统会发出内存警告,这时得回收一些不需要再使用的内存空间.比如回收一些不需要使用的对象.变量 ...

  7. iOS 非ARC基本内存管理系列 5-autorelease方法使用总结

    autorelase:可以将对象交给自动释放池中,释放池销毁的时候对里面的对象做一次release操作代码如下 @autoreleasepool { Person *person = [[[Perso ...

  8. iOS 非ARC基本内存管理系列 4-autorelease方法和@autoreleasepool

    1.autorelease 基本用法 对象执行autorelease方法时会将对象添加到自动释放池中 当自动释放池销毁时自动释放池中所有对象作release操作 对象执行autorelease方法后自 ...

  9. IOS 非ARC开发内存管理的几条规则

    关于ios内存管理.在开发过程中,内存管理很重要,我简单说明一下. 1.正确用法 UIView *v = [[UIView alloc] init]; //分配后引用计数为1 [self.view a ...

随机推荐

  1. Dijkstra最短路径算法[贪心]

    Dijkstra算法的标记和结构与prim算法的用法十分相似.它们两者都会从余下顶点的优先队列中选择下一个顶点来构造一颗扩展树.但千万不要把它们混淆了.它们解决的是不同的问题,因此,所操作的优先级也是 ...

  2. Particle Editor 无法启动此程序,因为计算机中丢失MSCP110.dll。尝试重新安装该程序以解决此问题。

    昨天下载了一个Particle Editor V2.1,打开时显示下面错误 网上百度了也不知是什么原因,回到家在另一台电脑上打开就行了,很奇怪... 两台电脑vs一台是vs2010,家里的一台是vs2 ...

  3. QPixmap 和 HBITMAP互转

    Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = 0); 声明这一句后, 就可以 ...

  4. 利用OPENSSL 实现MD5加密。

    #include <stdio.h> #include "openssl/evp.h" #include "openssl/md5.h" #incl ...

  5. python(5)–sys模块

    sys.argv 命令行参数list, 第一个元素是程序本身路径 sys.exit(n) 退出程序,退出时输入信息n sys.version 获取python解释程序的版本信息 sys.maxint ...

  6. 给jdk写注释系列之jdk1.6容器(3)-Iterator设计模式

    前面讲了两种List,一种基于数组实现的ArrayList,一种基于链表实现的LinkedList,这两种list是我们工作中最常用到的List容器.当然数组和链表也是两种常见的基本数据结构,其他基本 ...

  7. javaweb学习总结七(XML语言作用、语法)

    一:XML语言的概念以及作用 1:xml概念:extensible Markup language,可扩展行标记语言,因为html的语法比较混乱,不够严谨. 用html写的系统不好维护,所以w3c组织 ...

  8. centos7重置root开机登录密码

    今天忘记了centos7 root登录的密码,本来要好好的做个图文的教程也好啊,但是忘记截图什么的,就不在重复的工作了, 参考了下面的两个链接重置了密码,结合使用效果更好哦,嘿嘿.. 下次要是再遇到这 ...

  9. 关于简明Vim练级攻略

    本文装载于:http://coolshell.cn/articles/5426.html vim的学习曲线相当的大(参看各种文本编辑器的学习曲线),所以,如果你一开始看到的是一大堆VIM的命令分类,你 ...

  10. [ImportNew]Java中的Timer类和TimerTask类

    http://www.importnew.com/9978.html java.util.Timer是一个实用工具类,该类用来调度一个线程,使它可以在将来某一时刻执行. Java的Timer类可以调度 ...