初学者关于内存的思考(不断加深不断更新中)

简介:

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。
http://cocoadevcentral.com/d/learn_objectivec/                    原链接

 

- (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,如需转载请自行联系原作者


 

相关文章
|
1月前
|
存储 缓存 IDE
嵌入式开发中的几个有用的经验!
嵌入式开发中的几个有用的经验!
21 0
|
7月前
|
算法 编译器 程序员
嵌入式C语言代码优化方案(深度好文,建议花时间研读并收藏)
嵌入式C语言代码优化方案(深度好文,建议花时间研读并收藏)
114 0
|
9月前
|
设计模式 算法 开发工具
软件设计师总结-含括学习方法和学习过程,可参考(上)
软件设计师总结-含括学习方法和学习过程,可参考(上)
|
9月前
|
设计模式 算法 搜索推荐
软件设计师总结-含括学习方法和学习过程,可参考(下)
软件设计师总结-含括学习方法和学习过程,可参考(下)
|
9月前
|
SQL 安全 搜索推荐
学编程遇到问题,如何更好地提问?
不要只把你不懂的地方拿出来问而不提及问题的前因后果,否则回答者可能无法明白你的问题。尽量客观描述问题,而不是只说自己的理解和假设。在客观描述的基础上,你可以再加上自己的判断和尝试解决的结果。
|
算法
重温算法,加深理解
算法在开发中的地位我们都很清楚,但是呢实际上项目里用到的算法并不是很多,虽然不是必须但是我们还是要懂算法,理解算法,运用算法。前几年肝了很多算法,但是这玩意不经常练习就会忘记,今天就重新把算法捡起来吧。
72 0
重温算法,加深理解
|
算法 机器学习/深度学习 BI
干货 | 关于机器学习的知识点,全在这篇文章里了
本文为大家介绍机器学习的魅力与可怕。
3850 0
|
机器学习/深度学习 Python 人工智能
教程 | 一文读懂自学机器学习的误区和陷阱(附学习资料)
本文为你指出一些自学的误区,推荐学习资料,提供客观可行的学习表并给出进阶学习的建议。
4792 0
|
Web App开发 缓存 前端开发
前端知识体系整理(不断更新)
前端知识体系整理(不断更新) ——人脑不是机器,记忆都会退化,我们需要文档辅助作知识沉淀 javascript 基本功 语言特性 数据类型: Undefined, Null, Bollean, Number, String Object、Ar...
1261 0