OC基础—内存管理之@property及其参数(补充新知识:循环引用和@class)
2014-04-26 23:48
459 查看
------ android培训、java培训、期待与您交流! ----------
内存管理之@property
内存管理之@property:
我们可以利用@property简化我们内存管理代码。
之前我们手管理内存的时候,总要写大量相同的set,get方法,来确保内存管理的严谨性,但是这样的代码没有什么技术含量,而且量又大,不利于我们编写有用代码,这时我们可以利用@property来自动生成这些管理内存的get set方法。
现在我们有Person类和Book类的组合:看一下Person类
Person.h
Person.m
现在我们可以看到只要在@property后面加一个retain那么,.m文件中自动生成的set方法就是这个样子的
这样就不需要我们自己来管理set方法的内存了,也不用再写那些臃肿的代码了,只需要一句话
@property (retain) Book *book;
就可以自动生成那些重发的代码了。
当人@property是不会自动给你生成dealloc方法的,所以的dealloc方法还是要我们自己来写的,不要忘了对象的release。
@property参数
@property不光有retain这个参数,他有四大类参数
1.内存管理相关的参数
* retain: release旧值,retain新值(适用于OC对象)
* assign: 直接赋值 (默认)
* copy : release旧值,copy新值
2.是否生成set方法
* readwrite : 同时生成setter和getter的声明与实现(默认)
* readonly : 只会生成getter方法的声明与实现
3.多线程管理
* nonatomic : 性能高(一般就用这个)
* atomic : 性能低(默认)
4.setter和getter方法名称
* seteer : 决定了set方法的名称 一定要加:
* getter : 决定了getter方法的名称(一般用在BOOL类型)
来一个例子:
循环引用:
循环引用:我们来看个例子
两个类Person和Card
这就是循环引用,你引用我我引用你。
但是像上面这一样写会报错,Person.h里#import “Card”,Card.h里#import “Person.h”,这样会报一个重复声明的错误。那么如何解决这种问题呢,这个时候我们就用到@class这个东西。如下
我们不用#import,而是声明一个类,不知道变量和方法,只知道名称用@class,像是在Person.h里面@class Card这样我们就可以
@property (nonatomic, retain) Card *card;
这样写,而不必在#import “Card”,这样可以防止重复引用,重复声明,等到我们在Person.m里用到Card的变量和方法时,在#import相应的.h文件。看一下Person.m文件
还有一个只一点就是,循环引用的是有就是两个不能同时使用retain这个@property参数,必须一个用retain一个用assign,对象无法被销毁。
总结一下:
1.@class :仅仅声明一个类,不包含类里的成员变量和方法,故无法访问。
2.开发中引用一个类的时候,规范(为了性能着想)
1. 在.h文件中用@class来声明类
2. 在.m文件中用#import来包含类的所有东西
为什么用@class而不用#import:
1. 可以解决循环引用问题
2. 可以提高性能
两端循环引用解决方案!!!(面试题)
1. 一端用retain
2. 一端用assign
------ android培训、java培训、期待与您交流! ----------
内存管理之@property
内存管理之@property:
我们可以利用@property简化我们内存管理代码。
之前我们手管理内存的时候,总要写大量相同的set,get方法,来确保内存管理的严谨性,但是这样的代码没有什么技术含量,而且量又大,不利于我们编写有用代码,这时我们可以利用@property来自动生成这些管理内存的get set方法。
现在我们有Person类和Book类的组合:看一下Person类
Person.h
#import <Foundation/Foundation.h> #import "Book.h" @interface Person : NSObject // retain:给旧值release,给新值retain // dealloc里还是要自己释放的 @property (retain) Book *book; @property (retain) NSString *name; @end
Person.m
#import "Person.h" @implementation Person //- (void)setBook:(Book *)book //{ // if ( book != _book) { // // // 对当前正在使用的车release // [_book release]; // // // 对新车做一次retain // _book = [book retain]; // } //} - (void)dealloc { [_book release]; [_name release]; [super dealloc]; } @end
现在我们可以看到只要在@property后面加一个retain那么,.m文件中自动生成的set方法就是这个样子的
- (void)setBook:(Book *)book { if ( book != _book) { // 对当前正在使用的车release [_book release]; // 对新车做一次retain _book = [book retain]; } }
这样就不需要我们自己来管理set方法的内存了,也不用再写那些臃肿的代码了,只需要一句话
@property (retain) Book *book;
就可以自动生成那些重发的代码了。
当人@property是不会自动给你生成dealloc方法的,所以的dealloc方法还是要我们自己来写的,不要忘了对象的release。
@property参数
@property不光有retain这个参数,他有四大类参数
1.内存管理相关的参数
* retain: release旧值,retain新值(适用于OC对象)
* assign: 直接赋值 (默认)
* copy : release旧值,copy新值
2.是否生成set方法
* readwrite : 同时生成setter和getter的声明与实现(默认)
* readonly : 只会生成getter方法的声明与实现
3.多线程管理
* nonatomic : 性能高(一般就用这个)
* atomic : 性能低(默认)
4.setter和getter方法名称
* seteer : 决定了set方法的名称 一定要加:
* getter : 决定了getter方法的名称(一般用在BOOL类型)
来一个例子:
Person.h文件 #import <Foundation/Foundation.h> @interface Person : NSObject @property (getter = isRich) BOOL rich; // 给get方法取名 @property (getter = abc, setter = setAbc:, nonatomic, readwrite, assign) int weight; // 参数是可以写在一起的 // setWight // weight @property int age; @property (readwrite) int height; @property (retain) NSString *name; @end
循环引用:
循环引用:我们来看个例子
两个类Person和Card
Person.h #import <Foundation/Foundation.h> #import "Card.h" @interface Person : NSObject @property (nonatomic, retain) Card *card; @end Card.h #import <Foundation/Foundation.h> #import "Person.h" @interface Card : NSObject @property (nonatomic, assign) Person *person; @end
这就是循环引用,你引用我我引用你。
但是像上面这一样写会报错,Person.h里#import “Card”,Card.h里#import “Person.h”,这样会报一个重复声明的错误。那么如何解决这种问题呢,这个时候我们就用到@class这个东西。如下
#import <Foundation/Foundation.h> // 声明一个类:告诉我们Card是一个类,不知道里面变量 方法 @class Card; @interface Person : NSObject @property (nonatomic, retain) Card *card; @end #import <Foundation/Foundation.h> @class Person; @interface Card : NSObject @property (nonatomic, assign) Person *person; @end
我们不用#import,而是声明一个类,不知道变量和方法,只知道名称用@class,像是在Person.h里面@class Card这样我们就可以
@property (nonatomic, retain) Card *card;
这样写,而不必在#import “Card”,这样可以防止重复引用,重复声明,等到我们在Person.m里用到Card的变量和方法时,在#import相应的.h文件。看一下Person.m文件
#import "Person.h" #import "Card.h" // 在这里导入 @implementation Person - (void)dealloc { NSLog(@"person被销毁了"); [_card release]; [super dealloc]; } @end
还有一个只一点就是,循环引用的是有就是两个不能同时使用retain这个@property参数,必须一个用retain一个用assign,对象无法被销毁。
总结一下:
1.@class :仅仅声明一个类,不包含类里的成员变量和方法,故无法访问。
2.开发中引用一个类的时候,规范(为了性能着想)
1. 在.h文件中用@class来声明类
2. 在.m文件中用#import来包含类的所有东西
为什么用@class而不用#import:
1. 可以解决循环引用问题
2. 可以提高性能
两端循环引用解决方案!!!(面试题)
1. 一端用retain
2. 一端用assign
------ android培训、java培训、期待与您交流! ----------
相关文章推荐
- 黑马程序员--ios基础--oc内存管理--@property参数、循环引用、autorelease
- OC基础--内存管理中的@property关键字以及其参数
- 七.OC基础加强--1.内存管理 2.野指针,内存泄露 3.set方法的内存管理 4.@property参数 5.@class和循环retain的使用 6.NSString的内存管理
- oc -7 内存管理 相关参数 循环引用
- OC_语法入门_day5_内存管理_计数器/set方法/property的参数/循环引用/自动释放池
- 黑马程序员——OC基础---内存管理(引用计数器,多对象内存管理,set方法的内存管理,模型设计,循环引用)
- OC基础-内存管理-@property以及它的参数
- 黑马程序员--OC自学笔记---07内存管理、@property参数、@class、autorelease
- Objective-C—引用计数器、多个对象之间的内存管理、set方法的内存管理、@property参数、循环引用
- 黑马程序员--IOS_内存管理_@class和循环引用的问题。
- Objective-C基础学习笔记(八)-内存管理-autorelease使用-property创建对象的内存管理-循环引用的内管管理
- OC基础—内存管理之引用计数器
- OC加强day1-内存管理的范围、MRC与ARC、property参数,retain死循环、NSSstring简解、自动释放池、堆栈等得存储方式
- OC基础—@property和@synthesize(附带新知识 新类型id)
- Objective-C(十五、内存管理,MRC,循环引用,dealloc和setter方法)——iOS开发基础
- OC_内存管理(二)对象复制、循环引用问题、自动释放池
- OC-026.内存管理中循环引用的问题
- 【PHP基础知识】——服务器相关参数及其含义
- c++ 基础知识(输入输出、namespace命名空间、引用、函数重载模版、内存管理)
- oc基础-oc中单个对象的内存管理的一些基础知识