Objective - C基础: 第五天 - 2.多个对象之间的内存管理

在前面, 我们知道了OC中内存管理的机制, 引用计数, 也对引用计数有了基本的认识, 有些人可能会说, 引用计数而已, 不就是+1, -1么, 有多难?  的确, 在单个对象中的操作的确不难, 但如果是在多个对象之间操作呢? 这个就难了, 为什么这么说? 下面我们来看看示意图:




在示例图中, 有两个对象在调用Book, 那么Book的引用计数就为2, 每当释放一个对象Book的引用计数就-1, 其实这个关系到一些比较复杂的操作, 如果你释放了Student对象, 并没有把它的指针也清零, 那么Book这个对象就不会被释放, 一直存在于内存中, 当然, 只释放Person对象也是一样, 所以在我们需要思考更多的问题, 看看哪个对象没有被释放, 哪个对象的指针没有清零等等....





前面我们也说过, 谁通过alloc,new, copy或者[mutable]copy等方法创建, 那么就必须得调用release, 或者autorelease去释放对象, 这里有几个方法我们暂时没讲, 先不去理会.




还有一点就是谁retain, 那么就是谁release, 有始有终, 有增有减, 曾经让对象+1, 那么最后就必须让对象-1.



来看看代码例子:

<span style="font-size:12px;">#import <Foundation/Foundation.h>

@interface Person : NSObject
{
    Book *_book;
}
- (void)setBook:(Book *)boook;
- (Book *)book;

@end

@implementation Person
- (void)setBook:(Book *)boook
{
    _book = book;
}
- (Book *)book
{
    return _book;
}
@end</span>

<span style="font-size:12px;">#import <Foundation/Foundation.h>

@interface Book : NSObject
{
    int _price;
}
- (void)setPrice:(int)price;
- (int)price;
@end

@implementation Book
- (void)setPrice:(int)price
{
    _price = price;
}
- (int)price
{
    return _price
}
@end</span>

#import <Foundation/Foundation.h>
#import "Book.h"
#import "Person.h"
int main()
{
    Book *b = [[Book alloc] init];
    Person *p = [[Person alloc]init];


    [b release];
    b = nil;

    [p release];
    p = nil;
    return 0;
}


经过我们这么一些, 那么首先消失的就是b这个对象, 并且它的指针也会清零, 那么Book这个对象就会被释放, 看上去貌似没问题, 其实问题大大滴, 下面我们看看释放后的示意图:



PS: b指向Book对象的这根线是虚线, 代表的是已经被清零.


按照例子来讲, 我们所画的示意图就是和例子一样的结果, Book对象是被释放了, 但在Person对象里面, 还有一个_book指向着Book对象, 在这样子的情况下, 合理吗? 答案肯定是否定的.


那么我们应该怎么做呢?

<span style="font-size:12px;">@implementation Person
- (void)setBook:(Book *)boook
{
	_book = [book retain];
}
- (Book *)book
{
	return _book;
}
- (void)dealloc
{
	[_book release];
	NSLog(@"对象被释放了");
	[super dealloc];
}
@end</span>

只有这样子, 才可以使得Book被释放的时候, _book还有效, 并且只有通过Person对象被释放, 才可以完全的把Book对象给释放.

原理就是:



这样子我们就遵循了内存管理的原则, 永远都不会有错, 而一当b对象不想拥有Book对象的时候, 那么就可以释放, 并且清空它的指针, 但Person对象还拥有Book, 所以Book对象的计数器是1, 这样子程序就不会产生内存泄漏.






最后, p对象release了, 那么Book对象和Person对象的计数器都变为0, 全部对象被释放, 并且指针清零, 非常严禁的内存管理.







好了, 这次我们就讲到这里, 下次我们继续~~

posted @ 2015-01-25 23:04  背着吉他去流浪  阅读(181)  评论(0编辑  收藏  举报