从非ARC代码调用ARC方法

时间:2012-12-13 11:41:11

标签: objective-c ios automatic-ref-counting

我有一个使用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语句的评估点保留该值,然后保留所有本地范围,然后平衡保留,同时确保该值存在于调用边界内。在最坏的情况下,这可能涉及自动释放,但调用者不得假设该值实际上在自动释放池中。

该文件是否意味着我应该总是释放该对象,因为我不能假设该对象是自动释放的?

4 个答案:

答案 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。