objective-c对内存管理的疑问

我是从xcode 4才开始认真学习ios开发,但是由于它用的是LLVM 3,所以导致我在看很多文档时会发现很多令人疑惑的地方。

例如在以前的很多代码中,一个对象被alloc然后被使用完后,会立即调用一个release方法。比如类似下面的代码

ClassA *a = [[ClassA alloc] init];
ClassB *b = [[ClassB alloc] init];

[b setProperty:a];
[a release];

这种类似的代码很让人费解,我的猜测,如果这个代码可以正常运行的话,那么release方法实际并不是一个实际释放的方法,它只会做一个类似标记的玩意,在生命周期结束后再自己释放。

我依稀记得objective-c中有一个retain的机制,那么是否在这里的release只是把retain的计数减一了呢?那么什么样的行为会导致retain计数加一呢?llvm 3里面为啥可以抛弃这种方法呢?

阅读 6.6k
2 个回答

先说release,不是直接释放内存,是引用计数-1,而当引用计数0的时候,sdk会gc掉这段内存。应用的main函数里可以看到,有初始化一个AutoRealesePool,就是干这个。
另外,每个对象都有autorelease方法,对他调用一把autorelease后,就不用手动release了。
再看示例代码,这个要看你 ClassB 里 property 的定义:
如果是@property (copy) ClassB * b,那么setProperty的时候内存里会复制一个a,付给b。则(a-> mema[rc=1], b->memb[rc=1])
如果是@property (retain) ClassB * b,就给a的引用计数+1,b还是指向这段内存。则(a-> mema[rc=2] <-b)
所以,setProperty以后,对a调用release的时候,就是把a指向的内存段的rc-1。copy的情况下,a已经不可以调用了,掉了就会BAD_ACCESS,retain的情况下,a还可以调用,因为他的rc=2-1=1。
再说llvm3里抛弃这个的问题,llvm3有个特性,叫ARC,就是AutoReferenceCount,rc被自动管理了。在ARC打开的文件中,release autorelease retain 都是不允许使用的。在XCode的编译规则中可以加参数选择是否使用ARC编译某个文件。
后ARC时代,要注意属性是函数局部的,还是类全局的这些,因为,开发者已经不需要手动回收内存,ARC会依据他的可见性,或者是生命周期去处理。在使用完某个对象后,要 =nil一下,ARC会马上干掉他。
最后,在前ARC时代几个简单的规则:
使用alloc创建的实例引用计 rc=1
作为addObject:等方法的参数 rc+=1
作为removeObject:等方法的参数 rc-=1
调用removeFromeOOXX方法 rc-=1
调用 retain rc+=1
调用 copy 复制一份 rc不变
调用 release rc-=1
---- 使用建议 ----
使用alloc创建后,一定要使用release释放,或调用autorelease交给系统管理
add以后,一定记得remove

新手上路,请多包涵

通常 为了不BAD_ACCESS 我在dealloc 里都是 self.property = nil ;

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏