博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
初学者关于内存的思考(不断加深不断更新中)
阅读量:5889 次
发布时间:2019-06-19

本文共 3684 字,大约阅读时间需要 12 分钟。

1、

从最简单的说起,先看例子,看注释:

-(void)fun1 {
str1 = @"我是str1"; NSLog(@"str1的conut: %d",[str1 retainCount]);//-1 之所以为-1,是因为直接赋值后,"我是str1"被放在常量区,没有所谓引用 } -(void) fun2 {
str2 = [NSString stringWithFormat:@"我是str2"]; NSLog(@"str2的count: %d",[str2 retainCount]);//1。注意:stringWithFormat里面已经包含alloc和autorelease了 //[str2 release];如果加了这句,程序就崩溃。因为已经包含了autorelese,下面fun4的str2就是非法引用 } -(void) fun3 {
str3 = [[NSString alloc]init]; str3 = @"我是str3"; NSLog(@"str3的count: %d",[str3 retainCount]);//-1 alloc跟init被忽略了,效果如fun1 } -(void) fun4 {
NSLog(@"str2:%@",str2); NSLog(@"str1:%@",str1); NSLog(@"str3:%@",str3); } 在外面:     NSLog(@"str2 final count:%d",[str2 retainCount]);//1 仍旧是1,因为由编译器来负责管理(autorelease)     NSLog(@"str3 final count:%d",[str3 retainCount]);//-1

由上面的代码示例可以看出直接赋值跟用*with*方法赋值的区别。

stringWithFormat里面已经包含alloc和autorelease。确切地说,*with*方法都包含了alloc以及autorelease 2、 在声明为@property (nonatomic, retain) UIAlertView *alert时,这里的retain不是摆设,而是retain了一次,这就刚好跟dealloc对应,在dealloc里面release 计数器加1了。所以在还没alloc之前,retainCount为1。
在.h中声明alert为成员变量,并设为property的retain属性   UIAlertView *tmpAlert = [[UIAlertView alloc]initWithTitle:tempStr message:nil delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定",nil]; self.alert = tmpAlert; [tmpAlert release]; [alert addSubview:view]; [alert show];
在上例子中,一般就这么用,不要直接轻易去对alert进行alloc,这样很容易出错。常见的做法如上,设一个临时变量tmpAlert,赋值给alert后就release掉。注意,是赋值 给self.alert,而不是alert。别忘了,self.alert = tmpAlert 这句话等价于[alert release];alert = [tmpAlert retain];(为什么?)所以,为了避免额外的 错误,尽量在.h中声明property/retain属性,要赋值的时候就用self.***。 3、成员变量跟property不一定要对应存在,没有成员变量只有property也是合法的,self.***访问的就是property。 4、对一个尚未分配内存的变量进行release是合法的。但是一旦你alloc+init了之后,就不能那么随便release。请看下面比较:
UIAlertView *alert = nil;    [alert release];//正确        UIAlertView *alert2 = [[UIAlertView alloc] init];    [alert release];    [alert release];//报错        NSString *str = nil;    [str release];//正确        NSString *str2 = [[NSString alloc] init];    [str2 release];    [str2 release];//正确!!!!!

可以看出,NSString类型是个特列,不管你有没有alloc分配内存给他,都可以随时release。

从这个例子我们也可以看出,对于工程里面的成员变量,不应该随意去设@property属性,因为这样会暴露给别的类。但是这时候会有这样的烦恼,没有了(retain),似乎后面的内存管理会变得麻烦些。所以产生了另外一种方式,在.m文件里面,凡是用该成员变量(假设为A)的地方,首先要在init里面把A置为nil,这是为了后面release的方便,不会出错(对nil对象release是不出错的)。然后凡是对该变量进行赋值的地方,都要先release,赋值完后再retain,养成习惯吧,兄弟。

 

5、@property、@synthesize

这两个关键字是让成员变量生成相应的setter、getter。setter里面已经包含了必要的retain、release。平时我们用self.****就是访问setter,而没加self的就是访问普通的成员变量。

看个例子:

 @interface Photo : NSObject

{

NSString* caption;

NSString* photographer;

}

- (NSString*) caption;//getter 

- (NSString*) photographer;

- (void) setCaption: (NSString*)input;//setter,注意其默认的名字set+***

- (void) setPhotographer: (NSString*)input;

@end

用@property实现简化如下:

@interface Photo : NSObject

{

NSString* caption;

NSString* photographer;

}

@property (retain) NSString* caption;

@property (retain) NSString* photographer;

@end

这里的retain意思是,setter应该对input进行retain。

/                    原链接

 

- (void) dealloc

{

self.caption = nil;

self.photographer = nil;

[super dealloc];

}

6.下面介绍几个个人比较容易混淆的东西,非常实用!先总说一下,原则是:

原则1:往数组里填东西或者删除东西,数组本身的引用计数不改变!!!!,变的是被拿去添加的元素,引用计数相应增减

原则2:往view添加subview或者removeview,superView本身引用计数都不改变!!!变的是被拿去添加的subview,引用计数相应增减

原则3:subview可分为两种,一种是不需要控制的静态view,一种是被设为成员变量长期控制的动态view。 假设subview添加到superview中,并且以后不打算做改变,则应这么写:

uiview *subview = new subview;//subview:1

//若是动态view,则是_subView = new subview;//subview:1

[superView addSubView:subview];//subview:2, superview:1

[subview release];//subview:1

静态view:在dealloc中就不用再释放了!因为大原则是“谁申请谁释放”,你只申请了一次,自然只需要释放一次。剩下的1个引用什么时候减掉呢?当superView释放的时候自己释放掉!

动态view:若是动态view,则完全可以跟静态view一样,这样的话Dealloc里面就是空空的,这也是可以的;另一种是在上述步骤中不做release操作,统统保留到dealloc中做

本文转自编程小翁博客园博客,原文链接:http://www.cnblogs.com/wengzilin/archive/2012/03/15/2398083.html,如需转载请自行联系原作者

 

你可能感兴趣的文章
javaWebSerivice学习篇4-WSDL文档结构图
查看>>
swift三方库
查看>>
python自定义线程池
查看>>
坑到了,EF执行带事物的存储过程
查看>>
杭州之行
查看>>
函数式宏定义用do...while(0)的好处
查看>>
oracle ORA-00917: missing comma 是因为少逗号
查看>>
策略模式简介
查看>>
UIViewController中loadView的用法(应当注意的几点)
查看>>
POJ NOI0105-42 画矩形
查看>>
Java 数组在内存中的结构
查看>>
《关爱码农成长计划》第一期报告
查看>>
entity framework 6 通用数据类
查看>>
读取FTP上的excel文件,并写入数据库
查看>>
vs2008快捷键极其技巧 转载
查看>>
window 7上安装Visual Studio 2017失败的解决方法
查看>>
Python数值计算:一 使用Pylab绘图(2)
查看>>
k8s集群监控布署
查看>>
JAVA DataOutputStream和DataInputStream
查看>>
系统集成项目管理(二)
查看>>