黑马程序员——IOS基础——OC内存管理

------- android培训java培训、期待与您交流!

=====================引用计数器开始====================

基本类型数据存放在栈中,对象存放在堆中

栈中的数据系统自动回收

堆空间中的数据动态分配,不能自动分配,容易引起内存泄露

需要给对象发送消息,让它回收,即调用对象的回收方法

1.系统如何判断对象是否需要回收

需要理解对象内部结构:

每一个OC对象内部都有一个   引用计数器  (即被引用的次数),4个字节存储空间

当减为0时,回收

刚创建时,为1

2.引用计数器的作用

当使用allocnew或者[mutable]copy创建一个新对象时,默认计数器为1

如果对象计数器不为0,他就不会被回收,一直在内存中

3.引用计数器的操作

>给对象发送一条retain消息,可以使对象计数器+1(retain方法返回对象本身)

>给对象发送一条release消息,可以使对象计数器-1

>retainCount返回引用计数器的值

4.引用计数器的销毁

>当一个对象的引用计数器为0时,他会被销毁,所占用的内存会被回收

>当一个对象被销毁时,系统会自动向对象发送一条dealloc消息

>一般会重写dealloc方法,并且一定要调用[super dealloc],并且放在最后在这里释放相关资源


重写dealloc方法来看程序是否被回收:

- (void)dealloc{
	NSLog(@"对象被回收");

	//super的dealloc一定要调用,而且要放到最后面
	[super dealloc];
}


//调用:

原则:一调用alloc,就得调用一次release;一调用retain,就得调用一次release

int main(){
	Person *p = [[Person alloc] init];
	NSUInteger c = [p retainCount];//结果是1
	//[p release];//计数器-1,为0,在main函数还没有结束就已经回收了对象内存
	[p retain];//返回对象本身,计数器+2
	return 0;
}


僵尸对象已经被回收内存的对象

野指针指向僵尸对象(不可用内存)的指针

1.此时会报错:EXC_BAD_ACCESS------由于访问了一块坏的内存(已经被回收,不可被访问的内存)

2.如果继续使用对象调用任何方法(包括[p retain]),则会报错:-[Person setAge:]: message sent to deallocated instance 0x100109a10----会出现闪退

如何避免:设置p=nil    变为空指针,p指针就不存在,给空指针发送消息就不会报错(即p调用方法)

OC中不会报空指针错误

int main(){
	Person *p = [[Person alloc] init]; //1
	[p retain]; //2
	[p release]; //1
	[p release]; //0 被回收,此时Person对象成为僵尸对象,指针p称为野指针
	[p release];//会报错,
	return 0 ;
}


=====================引用计数器完====================

====================多个对象内存管理开始====================

当你想使用某个对象,应该对这个对象的计数器+1,不使用的时候-1

>谁创建  谁release

>谁retain 谁release


举个栗子:

Book.h中:

#import <Foundation/Foundation.h>
@interface Book : NSObject
//@property int price;//价格  由于涉及内存,不用property,因为它会屏蔽内存管理细节
{
	int _price;
}
- (void)setPrice:(int)price;
- (int)price;
@end 


Book.m中:

#import "Book.h"
@implementation Book
- (void)setPrice:(int)price
{
	_price = price;
}
- (int)price
{
	return _price;
}
//需要重写dealloc方法
- (void)dealloc
{
	NSLog(@"Book对象被回收");
	[super dealloc];
}

@end


Person.h中:

#import <Foundation/Foundation.h>
#import "Book.h"
@interface Person : NSObject
{
	Book *_book;
}
- (void)setBook:(Book *)book;
- (Book *)book;
@end


Person.m中:

#import "Person.h"
@implementation Person
- (void)setBook:(Book *)book
{
	_book=[book retain];
}
- (Book *)book;
{
	return _book;
}
//需要重写dealloc方法
- (void)dealloc
{
	[_book release];//人挂了,当然书就不用了
	NSLog(@"Person对象被回收");
	[super dealloc];
}
@end


主函数:

#import <Foundation/Foundation.h>
#import "Person.h"
#import "Book.h"
int main(){
	Book *b = [[Book alloc] init];//书两种情况需要被release:1.换一本书 2.人挂了    所以在这两种情况都要加release
	Person *p1 = [[Person alloc] init];
	//p1想占用b一次
	[p1 setBook:b];//去Person.m中让book retain一次

	[b release];//b不想用Book对象了,就应该让指针变空
	b=nil;

	[p1 release];//p1不用了,就用p1把对象人中的计数器-1,这时候计数器为0,对象人就挂了,那人
	p1=nil;
	return 0;
}

==================== 多个对象内存管理完 ====================


------- android培训java培训、期待与您交流!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值