iOS经典讲解之Objective-C属性的内存管理原理
2015-09-27 12:02
435 查看
@在进行讲解属性的内存管理之前,先来看看之前我们使用实例变量时是怎样管理内存的:
我们创建两个相关联的类Person类和Pet类,来看看它们中的赋值和取值方法是怎样管理内存的:
Pet.h
属性是怎样管理内存的首先属性的语义控制类型:
语义控制:assign、copy、retain。assign一般用于非对象类型和代理(如int,
float等),retain(对象类型,如NSDictionary、NSArray)会使属性的引用计数加1,一般对象使用retain。copy如果想得到对象的副本,那么这个时候使用copy。默认是assign。
当使用assign时:就如同上面的对实例变量age的赋值方法
Pet.h
我们创建两个相关联的类Person类和Pet类,来看看它们中的赋值和取值方法是怎样管理内存的:
Pet.h
#import <Foundation/Foundation.h> @interface Pet : NSObject { NSString *_name; } // 声明赋值 取值方法 - (void)setName:(NSString *)name; - (NSString *)name; @endPet.m
#import "Pet.h" @implementation Pet // 实现赋值 取值方法 - (void)setName:(NSString *)name { if (_name != name) { [_name release]; // 字符串一般用copy _name = [name copy]; } } - (NSString *)name { return _name; } // 释放实例变量 -(void)dealloc { [_name release]; [super dealloc]; } @endPerson.h
#import <Foundation/Foundation.h> #import "Pet.h" @interface Person : NSObject { // 声明三个不同类型的实例变量 Pet *_pet; NSString *_name; NSInteger _age; } // 声明赋值 取值方法 - (void)setPet:(Pet *)pet; - (Pet *)pet; - (void)setName:(NSString *)name; - (NSString *)name; - (void)setAge:(NSInteger)age; - (NSInteger)age; // 测试方法 - (void)test; @endPerson.m
#import "Person.h" @implementation Person // 实现赋值 取值方法 - (void)setPet:(Pet *)pet { if (_pet != pet) { [_pet release]; // 对象类型使用retain获得所有权,然后在dealloc方法中释放 _pet = [pet retain]; } } - (Pet *)pet { return _pet; } - (void)setName:(NSString *)name { if (_name != name) { [_name release]; // 字符串一般使用copy获得所有权,然后在dealloc方法中释放 _name = [name copy]; } } - (NSString *)name { return _name; } - (void)setAge:(NSInteger)age { // 基本数据类型不需要管理内存,因为不涉及引用计数的变化 _age = age; } - (NSInteger)age { return _age; } // 实现测试方法 - (void)test { NSLog(@"%@:我今年%ld岁,我有只宠物叫%@", _name, _age, [_pet name]); } // 释放实例变量 -(void)dealloc { [_name release]; [_pet release]; [super dealloc]; } @end接下来我们来看看属性是怎么写的:大家知道使用属性系统会自动声明并实现赋值(setter)和取值(getter)方法,不需要我们再来声明和实现赋值和取值方法,并且还自动给我们声明了带下划线的实例变量,给我们开发带来了极大的方便。虽然不需要我们再来操作赋值和取值方法,那他的实现原理我们还是要做到心中明白的。
属性是怎样管理内存的首先属性的语义控制类型:
语义控制:assign、copy、retain。assign一般用于非对象类型和代理(如int,
float等),retain(对象类型,如NSDictionary、NSArray)会使属性的引用计数加1,一般对象使用retain。copy如果想得到对象的副本,那么这个时候使用copy。默认是assign。
当使用assign时:就如同上面的对实例变量age的赋值方法
- (void)setAge:(NSInteger)age { // 基本数据类型不需要管理内存,因为不涉及引用计数的变化 _age = age; }当使用copy时,就如同上面的对实例变量name的赋值方法
- (void)setName:(NSString *)name { if (_name != name) { [_name release]; // 字符串一般使用copy获得所有权,然后在dealloc方法中释放 _name = [name copy]; } }当使用retain时就如同上面对实例变量pet的赋值方法
- (void)setPet:(Pet *)pet { if (_pet != pet) { [_pet release]; // 对象类型使用retain获得所有权,然后在dealloc方法中释放 _pet = [pet retain]; } }对于使用实例变量的代码用属性来替换的话,代码量缩短很多,下面替换上面的代码。
Pet.h
#import <Foundation/Foundation.h> @interface Pet : NSObject @property (nonatomic, retain) NSString *name; @endPet.m
#import "Pet.h" @implementation Pet // 释放属性 -(void)dealloc { [_name release]; [super dealloc]; } @endPerson.h
#import <Foundation/Foundation.h> #import "Pet.h" @interface Person : NSObject @property (nonatomic, retain) Pet *pet; @property (nonatomic, copy) NSString *name; @property (nonatomic, assign) NSInteger age; // 测试方法 - (void)test; @endPerson.m
#import "Person.h" @implementation Person // 实现测试方法 - (void)test { NSLog(@"%@:我今年%ld岁,我有只宠物叫%@", _name, _age, [_pet name]); } // 释放属性 -(void)dealloc { [_name release]; [_pet release]; [super dealloc]; } @end注意:如果使用属性,重写set和get方法时,系统会找不到相应的实例变量,这时需要重新声明实例变量,如果重写其中一个则不需要。
相关文章推荐
- The project was not built since its build path is incomplete. Cannot find the class file for java.lang.Object
- java中object类的学习
- 简介Java编程中的Object类
- JavaScript高级程序设计之引用类型之Object 类型第5.1讲敏敏笔记
- iOS经典讲解之Objective-C关联对象的内存管理
- Object Identification #Facebook Relay文档翻译#
- structure-object structure-object-pointer
- Objective-C 分数加减乘除
- Halcon对象Hobject转换为.net对象Bitmap
- 【IOS 开发学习总结-OC-20】★★★objective-c面向对象——协议(protocol)
- org.springframework.orm.hibernate3.HibernateSystemException: a different object with the same identi
- 【IOS 开发学习总结-OC-19】★★objective-c面向对象之——类别与扩展
- NSObject的描述(+description)方法和对象的描述(-description)方法,NSLog默认输出的修改(后知后觉)
- Objective-C 基础知识之 (十八):Copy NSString的Copy现象
- Objective-C 基础知识之 (十七):内存管理原则二
- Objective-C 基础知识之 (十六):内存管理原则一
- Objective-C 基础知识之 (十五):KVC
- Objective-C 基础知识之 (十四):属性 Property 点语法
- Objective-C 基础知识之(十三):类目、延展、协议、代理等的基本概念
- Objective-C 基础知识之(十二):NSDate