我有一个使用ARC库的非ARC项目。如果我应该释放库方法返回的对象,我很困惑。这是一些例子:
- (void)test{
LibObject* obj1 = [[LibObject alloc] init];
LibObject* obj2 = [obj1 otherObj];
[obj1 release]; //should I release it?
[obj2 release]; //should I release it?
}
据我所知,如果对象在自动释放池中,我应该不管它。否则,我应该释放它。
然而,the ARC document表示
当从这样的函数或方法返回时,ARC在return语句的评估点保留该值,然后保留所有本地范围,然后平衡保留,同时确保该值存在于调用边界内。在最坏的情况下,这可能涉及自动释放,但调用者不得假设该值实际上在自动释放池中。
该文件是否意味着我应该总是释放该对象,因为我不能假设该对象是自动释放的?
答案 0 :(得分:3)
请参阅“高级内存管理编程指南”中的Memory Management Policy:
您拥有自己创建的任何对象
您可以使用方法创建对象 其名称以“alloc”,“new”,“copy”或“mutableCopy”开头(for 例如,alloc,newObject或mutableCopy)。您不得放弃您不拥有的对象的所有权
这些规则与使用ARC编译的方法一致。 在ARC documentation中,第一类中方法的行为在“3.2.2。保留的返回值”中描述:
从这样的函数或方法返回时,ARC保留该值 在评估退货声明时,......
表示调用者必须释放该对象。
第二类中的方法在“3.2.3。未保留的返回值”中描述:
从这样的函数或方法返回时,ARC保留该值 在评估退货声明时,然后全部离开 本地范围,然后平衡保留......
表示调用者不得释放该对象。
所以在你的例子中:
LibObject* obj1 = [[LibObject alloc] init];
LibObject* obj2 = [obj1 otherObj];
[obj1 release]; //should I release it? --> YES
[obj2 release]; //should I release it? --> NO
您拥有obj1
,因为它是使用alloc
创建的,因此您必须释放obj1
。
您不拥有obj2
,因此您不得发布它。
注意:如果您在代码上运行Xcode静态分析器,它会准确显示违反这些规则的位置。
答案 1 :(得分:2)
当您从启用ARC的类获取对象到启用非ARC的类时,您有责任管理内存。
ARC只是在编译期间将ARC保留代码中的retain,release放在中。它不会管理处于非ARC模式的其他类或对象的内存。
您应该在需要之后释放这些物品。
答案 2 :(得分:0)
我的理解是,如果您对此文件使用编译器标志-fno-objc-arc
,则需要自己处理保留/释放。所以你应该致电[obj1 release]
。如果您不应该自己调用它,编译器会相应地警告您。
答案 3 :(得分:0)
据我所知,在您的非ARC代码中,您只需像往常一样使用启用ARC的库进行所有保留/释放(就像与其他非ARC代码交互一样)。
我创建了一个简单的应用来证明这种行为。
测试代码 - 编译没有 ARC
- (void)testARC
{
ARCLib *al = [[ARCLib alloc] init];
NSLog(@"%p retainCount = %u", al, [al retainCount]);
[al release];
ARCLib *al2 = [ARCLib arcLib];
NSLog(@"%p retainCount = %u", al2, [al2 retainCount]);
}
ARCLib - 使用 ARC编译
@implementation ARCLib
+ (id)arcLib
{
return [[self alloc] init];
}
- (id)init
{
self = [super init];
if (self)
{
NSLog(@"%p init",self);
}
return self;
}
- (void)dealloc
{
NSLog(@"%p dealloc",self);
}
@end
<强>结果强>
2012-12-13 20:15:21.879 ARCTest[15206:907] 0x1e821500 init
2012-12-13 20:15:21.883 ARCTest[15206:907] 0x1e821500 retainCount = 1
2012-12-13 20:15:21.884 ARCTest[15206:907] 0x1e821500 dealloc
2012-12-13 20:15:21.885 ARCTest[15206:907] 0x1dd26060 init
2012-12-13 20:15:21.886 ARCTest[15206:907] 0x1dd26060 retainCount = 1
2012-12-13 20:15:21.893 ARCTest[15206:907] 0x1dd26060 dealloc
回答您的问题
你应该释放你的obj1,但不需要释放obj2。