关于内存管理,写一个简单易懂的教程

【ios】关于内存管理,写一个简单易懂的教程  

2012-06-28 15:39:39|  分类: ios内存管理 |  标签: |字号 订阅

管理原则:

谁用谁retain,谁retain的谁release。

复制代码
1 ClassA *obj1 = [[ClassA alloc] init];  2 //这里你申请了一块内存地址,指针obj1指向了这块内存地址,同时你给它retain了一下(retain,copy,alloc这几个方法都相当于把retaincount加一),此时obj1所指向的这块内存地址retaincount为1。 3  4 ClassA *obj2=obj1; 5 [obj2 retain]; 6 //obj1和obj2同时都指向了上面所述的内存地址,我假设这块内存为A,那么A这块内存的retaincount为2。 7 [obj1 release]; 8 [obj2 release]; 9 //最后不用的时候,需要释放了
复制代码

二、不要随便看到retaincount多就给它释放
很多朋友在学完内存管理后喜欢玩消除,不该释放的他去释放,举个例子

UIViewController *ct1=[[UIViewController alloc] init]; [self.navigationcontroller pushViewController:ct1 animated:YES]; [ct1 relese];

 

这 里,初始化一个viewcontroller,然后用导航push进来,最后释放这个viewcontroller,很多人在这里操作完毕后,继续打印 ct1的retaincount,发现它的retaincount不为0,就继续release,这里是非常错误的方法,直接导致程序崩溃,继续看以上原 则“谁用谁retain,谁retain的谁release”,你用的时候,初始化,并retain了一次,最后你release了一次,到此结束!之后 不管你发现它的retaincount为几,你都不该再release。你打印出来的retaincount并不是你retain的,而是系统框架本身 retain的,由框架本身来处理,开发者不必理会。
类似还有很多,数组的addobject、addsubview等等很多方法,都是框架自己家retain的,开发者本身retain后release,不必理会它的retaincount。
另 外插一句,如果是多人协同开发,这种情况最容易碰到,别人传递一个参数过来,你拿过来retain后使用,使用完毕release,发现 retaincount还不是0,于是你继续release,这样你就把你同伴retain的计数给release掉了,当他下次使用的时候发现崩溃了, 这种情况会让你的团队浪费无数的时间来找原因。
三、关于属性
属性在.h文件中是这样声明的

@property(nonatomic,retain) Class *obj;

括号内第二个参数代表的意义是什么呢?
我们分析一下他内部的机制
@property (retain) Class* obj;@synthesize obj;实际上是gettersetter,有retain参数的property,内部代码如下

复制代码
-(Class *) getObj {          return obj; }  -(void) setObj:(Class *) value {          if (obj != value)          {                    [obj release];                    obj = [value retain];          } }
复制代码

愿意仔细分析的童鞋可以仔细研究一下,不太明朗的童鞋请听我说。

这个属性定义以后如何使用呢?我们只说赋值(也就是set)

self.obj=xxx; [self setObj:xxx]; obj=xxx;


赋值方法有以下几种,其中前两个是相同的,都是调用了setObj:方法同时也就导致了obj的retaincount增加了1,而第三个赋值方法并没有增加retaincount,只是将指针指向了xxx内存地址。
所以大家赋值时可以这样

Class *c=[[Class alloc] init]; self.obj=c;[c release]; //或者 Class *c=[[Class alloc] init]; [self setObj:c];[c release]; //或者 Class *c=[[Class alloc] init];obj=c;

 

属 性的这个机制是让你在整个self里(也就是当前类的实例里)一直保留这个obj的retaincount,所以你必须在此类的dealloc里将obj 的retaincount置零(你只需要release,如果你严格遵守“谁用谁retain,谁retain的谁release”的话)

-(void)dealloc {     [obj release];     [super dealloc]; }
这里,其实我主要要说明的就是属性的赋值方式用self.xxx=xxxx和xxx=xxxx是完全不同的赋值方式,大家切记!
四、autorelease对象
autorelease 对象就是自动释放对象,大家可能会疑惑,能自动释放,我还管理干嘛,我都用自动释放算了,事实不是这样的,自动释放确实好用,但是自己管理内存才能让项目 占用更小的资源,跑起来更流畅,大家可以手动管理加autorelease一起来使用,我先讲解一下autorelease对象到底是什么个情况。
首先,告诉大家autorelease对象什么时候才会被释放。
在main函数里有一个autorelease pool,自动释放池,所以在这个自动释放池里的autorelease对象都会在自动释放池结束的时候全部被释放。
大 家可能会问了,“难道所有的autorelease对象都是在程序退出的时候才被释放?”,答案当然不是,其实main函数中只是一个程序中众多自动释放 池中的一个,每个runloop都会隐性的创建一个自动释放池,啥是一个runloop?每个UIView创建、delegate回调等等都会创建一个自 动释放池,记得这个“等等”,意思就是有很多(如果大家想要详细了解runloop,可以去google)。所以大家不用担心autorelease对象 不会被释放。
很 多系统的方法,比如[NSArray array]、[NSString stringformat]等等返回的对象都是autorelease对象,这些对象是不需要手动释放的,如果手动释放会导致程序崩溃!切记!,原则就是 系统中所有没有使用alloc、copy、retain来创建的对象都是autorelease对象,大家千万别手动release
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值