ios笔记--retain,release介绍和setter方法的内存管理笔记

本文详细探讨了Objective-C与Swift两种语言在iOS开发领域的应用与区别,包括语言特性、优缺点及实际案例分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、什么情况下需要内存管理?

任何继承了NSObject的对象,对基本数据类型无效。

 

2、内存管理的原理?

每个对象内部都保存了一个与之相关联的整数,称为引用计数器。

当使用allocnew或者copy创建一个对象时,对象的引用计数器被设置为1

给对象发送一条retain消息,引用计数器值+1

给对象发送一条release消息,引用计数器值-1

当一个对象的引用计数器值为0时,那么它将被销毁,其占用的内存被系统回收,OC也会自动向对象发送一条dealloc消息。

可以给对象发送retainCount消息获得当前的引用计数器值。

 

3、什么叫野指针?

即当计数器已经为0了,还继续release,访问了不属于你的内存,这样就叫野指针错误。

防止出现野指针的做法:尽量不要在调用的文件中写释放,不然会出现一个地方释放了该对象,在另一个方法又出现调用的情况,这样就会出现野指针。所以最好在创建语句的文件中dealloc方法写release语句,因为无论谁创建了一个对象,最终销毁时都要调用一次dealloc方法。这样别人只管调用,不用管内存释放的问题了,可以保证内存不浪费。

例子如下:

Book.h文件中

#import<Foundation/Foundation.h>

@interface Book NSObject

@property int price;

@end

 

Book.m文件中

XCode4.5版本以上编写:只需在.h文件中写@property语句即可,不用在.m文件中写@sythesize了。

#import<Foundation/Foundation.h>

@implementation Book

@end

 

Student.h文件中

#import<Foundation/Foundation.h>

@implementation Student

-(void)setBook : (Book *) book;

-(Book *)book;

-(void)readBook;

@end

 

Student.m文件中

#import<Foundation/Foundation.h>

@implementation Student

#pragram mark -gettersetter

-(void) setBook : (Book *) book

{

_book = [book  retain];

}

 

-(Book *) book{

return  _book;

}

 

-(void)readBook{

NSLog(@”调用了readBook方法。”);

}

 

#pragma mark 回收对象

-(void)dealloc{

[self.book  release];//等价于[_book release];即销毁book对象

[super dealloc];

}

@end

 

main.m文件中调用

#import<Foundation/Foundation.h>

#pragram mark 私有方法

void test(Student *stu){

Book  *book  =  [[Book alloc] initWithPrice:3.5];//创建一个对象,计数器+1

stu.book  =  book;  //调用一次set方法,该方法内有retain操作,所以计数器会+1

[book  release];  //释放一次,计数器 -1,所以调用完该方法,book对象还可以继续使用

}

 

void test1(Student *stu){

[stu readBook];//因为book对象还没被销毁,计数器不为0,所以这样调用就不会出现空指针

}

 

int main(int argc,const char * argv[])

{

@autoreleasepool{

Student *stu  = [[Student alloc] initWithAge:10];//创建一个对象,Student计数器为1

test(stu);

test1(stu);

[stu  release];//释放stu对象,同时也会调用studealloc方法,该方法内部同时也会释放book对象,所以最终book对象也会被销毁掉,从而不会出现内存泄露的问题。

}

return 0;

}

 

第二种情况:当有两个指针对象都调用同一个变量的情况,内存释放例子如下:

Book.h文件中

#import<Foundation/Foundation.h>

@interface Book NSObject

@property int price;

@end

 

Book.m文件中

XCode4.5版本以上编写:只需在.h文件中写@property语句即可,不用在.m文件中写@sythesize了。

#import<Foundation/Foundation.h>

@implementation Book

@end

 

Student.h文件中

#import<Foundation/Foundation.h>

@implementation Student

-(void)setBook : (Book *) book;

-(Book *)book;

-(void)readBook;

@end

 

Student.m文件中

#import<Foundation/Foundation.h>

@implementation Student

#pragram mark -gettersetter

-(void) setBook : (Book *) book

{

[_book release];//先释放掉原来的book对象,即book1,如果缺少这句,会造成原来的对象变成野指针,没有释放。

_book = [book  retain];//然后再把book2对象赋值上去。

}

 

-(Book *) book{

return  _book;

}

 

-(void)readBook{

NSLog(@”调用了readBook方法。”);

}

 

#pragma mark 回收对象

-(void)dealloc{

[self.book  release];//等价于[_book release];即销毁book对象

[super dealloc];

}

@end

 

main.m文件中调用

#import<Foundation/Foundation.h>

#pragram mark 私有方法

void test(Student *stu){

Book  *book  =  [[Book alloc] initWithPrice:3.5];//创建一个对象,计数器+1

stu.book  =  book;  //调用一次set方法,该方法内有retain操作,所以计数器会+1

[book  release];  //释放一次,计数器 -1,所以调用完该方法,book对象还可以继续使用

Book *book2 =[[Book alloc] initWithPrice:4.5];

stu.book = book2;

[book2 release];

}

 

void test1(Student *stu){

[stu readBook];//因为book对象还没被销毁,计数器不为0,所以这样调用就不会出现空指针

}

 

int main(int argc,const char * argv[])

{

@autoreleasepool{

Student *stu  = [[Student alloc] initWithAge:10];//创建一个对象,Student计数器为1

test(stu);

test1(stu);

[stu  release];//释放stu对象,同时也会调用studealloc方法,该方法内部同时也会释放book对象,所以最终book对象也会被销毁掉,从而不会出现内存泄露的问题。

}

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值