
单个对象的内存管理非常简单无非就是alloc对应release,retain对应release。但是如果涉及到很多对象,而且对象与对象有联系的时候该怎么去管理对象的内存呢。
比如同样一本书有好3个人购买,那意味着3个人都在引用这本书。在内存中如图所示:

那么如果Person对象引用Book对象的话就必须给Book对象的引用计数+1,如果不再引用Book对象就要把Book对象中的引用计数减1。遵循"有加必有减"
1.多对象内存管理原则分析
2.谁创建谁release
如果通过alloc、new或[mutable]copy来创建一个对象,那么必须调用release或autorelease
换句话说,不是你创建的,就不用你去[auto]release
3.谁retain谁release
只要你调用了retain,无论这个对象是如何生成的,你都要调用release
4.总结原则
5.代码实现
/*
需求:有连个类Person类和Book类,实现让Person类获取到Book,也就是人要获取书;
如果Person类对象释放那么Book类对象也必须释放,也就是说一旦人没了,书也就没了
设计类:既然人要占有书,那么可以在人中包含一个书类型,然后让实际的书给人中的书赋值那么人就拥有书了
*/
内存结构如图:

代码实现:
/********************************** Person.h文件 *********************************/
#import "Book.h"
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
// 既然人要拥又书,那么在Person类定义一个Book类型的成员变量 _book
Book *_book;
}
// @PRoperty会隐藏底层内存管理 因此先不使用@property便于查看底层实现
// @property Book *book;
// 通过set方法为Person中的_book传入实际的book
- (void)setBook:(Book *)book;
- (Book *)book;
@end
/********************************** Person.m文件 *********************************/
#import "Person.h"
@implementation Person
// 为Person中的_book传入Book对象 类似于给了Person中的_book给了一本书
- (void)setBook:(Book *)book
{
// 既然人已经拥有了书 那么书的引用计数必须+1 因此调用书的retain方法
_book = [book retain];
NSLog(@"人拥有书了");
}
- (Book *)book
{
return _book;
}
// Person类对象在回收前调用方法
- (void)dealloc
{
[_book release];
NSLog(@"Person对象被回收");
[super dealloc];
}
@end
/********************************** Book.h文件 *********************************/
#import <Foundation/Foundation.h>
@interface Book : NSObject
@end
/********************************** Book.m文件 *********************************/
#import "Book.h"
@implementation Book
// Book类对象在回收前调用方法
- (void)dealloc
{
NSLog(@"Book对象被回收");
[super dealloc];
}
@end
/********************************** main文件 *************************************/
#import <Foundation/Foundation.h>
#import "Book.h"
#import "Person.h"
int main(int argc, const char * argv[])
{
Person *p = [[Person alloc] init];
Book *b = [[Book alloc] init];
// 为Person类对象中的_book传入实际的Book对象
[p setBook:b];
// 释放Person类对象
[p release];
// 既然Person类对象已经释放那么清除掉指向Person类对象的指针
p = nil;
// 既然Person类已经不可用了那么Book类对象也应该释放
[b release];
// 清空指向Book类对象的指针
b = nil;
return 0;
}