您好,匿名用户
随意问技术百科期待您的加入

objective-c对内存管理的疑问

0 投票

我是从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里面为啥可以抛弃这种方法呢?

用户头像 提问 2012年 12月1日 @ Janna 下士 (667 威望)
分享到:

1个回答

0 投票

先说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

用户头像 回复 2012年 12月1日 @ Aries 上等兵 (238 威望)
提一个问题:

相关问题

0 投票
1 回复 42 阅读
0 投票
1 回复 45 阅读
用户头像 提问 2012年 12月1日 @ Dante 上等兵 (290 威望)
0 投票
1 回复 35 阅读
用户头像 提问 2012年 12月1日 @ Berserker 上等兵 (157 威望)
0 投票
1 回复 36 阅读
0 投票
1 回复 31 阅读
用户头像 提问 2014年 1月20日 @ 阿尔托莉雅 下士 (587 威望)

欢迎来到随意问技术百科, 这是一个面向专业开发者的IT问答网站,提供途径助开发者查找IT技术方案,解决程序bug和网站运维难题等。
温馨提示:本网站禁止用户发布与IT技术无关的、粗浅的、毫无意义的或者违法国家法规的等不合理内容,谢谢支持。

欢迎访问随意问技术百科,为了给您提供更好的服务,请及时反馈您的意见。
...