Objective-C内存管理(中)

一.概述:

1.@property作用:

1.生成private修饰的私有的成员变量

2.生成成员变量的set/get方法的声明

3.生成成员变量的set/get方法的实现.

2.property参数:

@property(参数1,参数2,....)数据类型 名称;

3.MAC下的@property的四组参数:

与多线程相关的两个参数 nonatomic - atomic
与生成的setter方法的实现相关的参数 assign - retain
与生成只读、读写相关的参数 readonly - readwrite
是与生成的getter setter方法名字相关的参数 getter - setter


介绍与多线程相关的参数

atomic: 默认值,如果写atomic,这个时候生成的setter方法的代码就会被加上一把线程安全锁。
特点: 安全、但是效率低下。
nonatomic: 如果写nonatomic这个时候生成的setter方法的代码就不会加线程安全锁。
特点: 不安全,但是效率高。

生成的setter方法的实现相关的参数:

assign: 默认值,生成的setter方法的实现就是直接赋值。
retain: 生成的setter方法的实现就是标准的MRC内存管理代码,也就是先判断新旧对象是否为同1个对象,如果不是 release旧的 retain新的。
当属性的类型是OC对象类型的时候,那么就使用retain。
当属性的类型是非OC对象的时候,使用assign。


千万注意:
retain参数,只是生成标准的setter方法为标准的MRC内存管理代码,不会自动的再dealloc中生成relase的代码。所以,还要自己手动的在dealloc中release。

生成只读、读写的封装 :

readwrite: 默认值,代表同时生成getter setter。
readonly: 只会生成getter,不会生成setter

生成Set和get方法的名称:

默认情况下@property生成的getter setter方法的名字都是最标准的名字。

同时我们可以通过参数来指定@property生成的方法的名字。

getter = ”getter方法名字“ 用来指定@property生成的getter方法的名字。
setter = ”setter方法名字“ 用来指定@property生成的setter方法的名字。

注意:setter方法是带参数的所以要加1个冒号。
注意:如果使用getter setter修改了生成的方法的名字,在使用点语法的时候,编译器会转换为调用修改后的名字的代码。
 

注意:

1.无论什么情况都不要改setter方法的名字,因为默认情况下生成的名字就已经是最标准的了。
2.当属性的类型是1个BOOL类型的时候,可以修改这个getter的名字以is开头以提高代码的阅读性。

3.同1组参数只能使用1个,参数的顺序可以随意。


 二.循环引用:

      当两个类相互包含的时会出现循环引用的问题,造成无限递归,而导致无法编译通过。


解决办法: @class  类名

在B类或A类其中一方用 @class 类名 代替 #improt "类名",就行了。

比如在B类中@class"A.h"代替#import "A.h"

但是这样还是有一个问题,它仅仅告诉编译器某个名称是一个类,并没有把这个类中的 所有东西拷贝过来


1.#import 方式会包含被引用类的所有信息,包括被引用类的变量和方法;

2.@class 方式只是告诉编译器在 A.h 文件中 B *b 只是类的声明,具体这个类有什么信息,这里不需要知道,等实现文件中真正要用到时,才会去 查看 B 类中信息。

3.如果有上百个头文件都#import 了同一个文件,或者这些文件依次被#import,那么一旦最开始的头文件稍 有改动,后面引用这个文件的所有类都要重新编译一遍,这样对效率的影响也是可想而知的。相对来讲,使 用@class 方式就不会出现这种问题了。


4.在.m 实现文件中,如果需要引用到被引用类的属性或者方法时,还需要使用#import 方式引用被引用 类。


不过我建议,如果不用A类或B类里面的属性时候,建议都用@class;

在实际开发中:
(1) 在.h 文件中用@class 来声明类
(2) 在.m 文件中用#import 来包含类的所有东西


2.循环reatian问题:

观察上述情况,上述就是著名的循环引用问题,对于此类问题,“你包含我,我包含你”,里面相关的对象占 用的内存永远回收不了,解决办法很简单,与常规方法不同。

正常情况下导致循环引用的问题:

在 Person.h 文件中加上: @property (nonatomic, retain) Card *card;,

在 Card.h 文件中加上@property (nonatomic, retain) Person *person;。 

为了解决这个循环引用问题,我们应把其中一个retain改成assign,另一个不变即可。

比如把Card.h中的改为: @property (nonatomic, assign) Person *person; 

这样就可以解决循环引用的问题了。

综上,两端循环 retain 引用解决方案:

一端用 retain,一端用 assign

猜你喜欢

转载自blog.csdn.net/Null959_/article/details/81145567