1

来源:互联网 发布:dota2饰品淘宝店 编辑:程序博客网 时间:2024/06/05 10:13

http://blog.sina.com.cn/s/blog_8c50145e0100w62p.html


从某种角度讲,认识一个未知的新事物,一个比较好的办法就是,先观察她的“相”,了解她的基本表现形式,然后由相至其理。所谓“相由心生”,明代第一大忽悠高手王阳明认为,“心”即理,这个理就是天理,道理和自然规律等。后世人都喜欢把王阳明划到唯心主义一边,其实这是天大的骗局,如果王真的泉下有知,我估计他会从棺材里爬出来,臭骂你们这些乌龟王八蛋。以王的悟性,我想,根本不止后世人想的这么简单,王一生战功无数,从无败笔。纵观王的谋略,无一不用到”心“,这里的心,是指人心,人道。世人打仗,都是兵马未动,粮草先行。他却兵马未动,先攻心,先在心理上搞定对方,让敌方在心理上处于客体地位,不战而胜。毛ZD早年很崇拜王,毛的很多战术战略都有王的痕迹。

废话少扯,进入主题。ios框架的内存管理机制看似比较复杂,其实不然。一套把戏的制定,必然有她的道理。我认为ios框架的内存机制的本质是为了更好的让设计人员方便管理内存,减少程序中的内存泄露,在内存管理难度与性能之间找一个最佳的平衡点。 假设你开辟了一块新内存,并把内存地址付给指针A,后来你也想让指针B也共享这块内存,于是你把指针A付给指针B,这个时候,A和B都指向同一块内存。如果A在没有通知B的情况下,A擅自把把这块内存释放了,B使用这块内存的时候,程序必然会crash掉。

有没有办法在释放内存的时候,通知一下所有正在和将来要引用这块内存的所有指针呢?答应是有的,只不过这种通知,不是主动式通知。在objective-c中,通过给堆中开辟的内存设计一个计数器,这个计数器的初始值为0,在内存被开辟出来后,计数+1。当指针A不需要使用这块内存的时候,只要把计数器-1,这时候计数器计数变成0,ios框架会释放这块内存。

梁静茹有首歌是这样唱的,“有些事你不必问,有些人你不必等”。其实,有些事,你也不必纠结。在刚接触objective-c的时候,很多人会对oc中属性的assign,retain,copy关键字感到迷惑。其实,我想说,书不必读太多,况且有些书未必说清楚了。前面我说过,鬼把戏的制定,必然有她的道理。我们这样想一下,对于int,bool等基本类型,这些直接在栈上开辟的内存,oc无需管理他们内存计数器,这个时候我们一般用assign;对于在堆中开辟的内存,我们需要维护内存的计数器,我们还引用上面的那个例子,首次创建内存后,内存计数器+1,当指针A付给指针B的时候,在这个时候,我们需要给内存计数器再+1,告诉其他指针,我B也引用了这块内存,这个时候,retain正是做这个工作的,只是oc封装了这个过程。其实copy更好理解,如果指针A和指针B不想相互牵扯,A管理A的内存,B管理B的内存,copy正是为这个而生。

关于内存释放是一个永恒的话题,我只想说,在+和-之间保持平衡,如果是框架+的,那就让框架去-,别™多管闲事。如果是你+的,那也不能偷懒。不是所有的成员变量都要设置属性,释放带属性的成员变量的时候,按照oc的约定,我们只需要用self.属性=nil,至于为什么这样,可以研究一下retain属性的结构。

自动释放池,并不是什么好东西,如果不是万般无奈的情况下,我建议不使用autorelease构建对象。但是,在一个方法中返回一个对象的指针,这个时候,我们不方便管理方法返回的对象,这种情况,用autorelease是比较明智的选择。

不要轻易把autorelease对象付给retain属性,因为你很有可能忘记给属性设置nil。  

0 0
原创粉丝点击