当前位置: 代码迷 >> Iphone >> ARC下函数返回对象的生命周期
  详细解决方案

ARC下函数返回对象的生命周期

热度:68   发布时间:2016-04-25 05:48:28.0
求教:ARC下函数返回对象的生命周期
刚接触objective c,最近在学习的时候遇到这样一个问题,就是在ARC下,函数返回的对象无法在我预期的时间销毁。我把问题程序简化了一下:

.h文件:
// 用来测试对象销毁的简单类
@interface TestObj : NSObject
-(void)dealloc;
@end

// 内含一个可变数组,用来存储对象
@interface TestQueue : NSObject
{
    NSMutableArray* array;  // 对象存放在该数组中
    NSNumber* n0;               // 用来给数组元素占位的对象
}
-(id)initWithCount:(int)cnt;   // 以指定容量初始化数组
-(void)dealloc;
-(void) Push:(NSObject*)obj; // 向数组中存储对象
-(NSObject*)Pop;                  // 从数组中弹出对象,返回给调用者,问题就出在这里
@end

.m文件
@implementation TestObj

-(void)dealloc
{
    NSLog(@"TestObj dealloc\n");      // 输出对象销毁的提示
}

@end

@implementation TestQueue

-(id)initWithCount:(int)cnt
{
    if (self = [super init]) {
        array = [[NSMutableArray alloc] initWithCapacity:cnt];
        n0 = [[NSNumber alloc] initWithInt:0];

        // 用占位对象填充数组
        for (int i = 0; i < cnt; i++) {
            [array addObject:n0];
        }
    }
    return self;
}
-(void)dealloc
{
    [array removeAllObjects];
}

-(void) Push:(NSObject*)obj
{
    // 为了简单的说明问题,这里仅仅把对象放在了数组首元素
    [array insertObject:obj atIndex:0];
}
-(NSObject*)Pop
{
    // 这就是天杀的出问题的地方

    // 取出首元素
    NSObject* obj = (NSObject*)[array objectAtIndex:0];

    // 用占位对象替换首元素
    [array replaceObjectAtIndex:0 withObject:n0];

    // 将取出的元素返回给调用者
    return obj;
}

@end


下面是测试代码

        TestQueue* pTQ = [[TestQueue alloc] initWithCount:3];
        {
            // 代码段1
            {
                TestObj* pObj = [[TestObj alloc] init];
                [pTQ Push:pObj];
            }
            // 代码段2
            {
                TestObj* pObj = (TestObj*)[pTQ Pop];
                NSLog(@"------ 111111 ----- %@\n", pObj);
            }
            NSLog(@"------ 22222 ------\n");
        }

实际输出的结果是:
 ------ 111111 ----- <TestObj: 0xaa4eda0>
 ------ 22222 ------
 TestObj dealloc

而我预期的结果应该是:
------ 111111 ----- <TestObj: 0xaa4eda0>
 TestObj dealloc
------ 22222 ------

也就是说,我认为代码段2结束后,TestObj对象不再被任何人持有,就应该自动析构了,但事实并非如此。
为此,我对TestQueue类的Pop函数做了一下测试,修改为:
-(NSObject*)Pop
{
    //NSObject* obj = (NSObject*)[array objectAtIndex:0];
    [array replaceObjectAtIndex:0 withObject:n0];
    return nil;
}
这次输出结果为:
 TestObj dealloc
 ------ 111111 ----- (null)
 ------ 22222 ------
这结果我能理解,所以,问题就归结到了这行代码:
NSObject* obj = (NSObject*)[array objectAtIndex:0];
也就是,在ARC下,该如何控制函数返回对象的生命周期呢?
先在此拜谢各路大神!
------解决方案--------------------
你如果这么写,应该会按照你的预期...


@autoreleasepool {
                TestObj* pObj = (TestObj*)[pTQ Pop];
                NSLog(@"------ 111111 ----- %@\n", pObj);
}



------解决方案--------------------
楼上的方法可行。
RunLoop结束了,,,该RunLoop内分配的内存才会真正的释放。
------解决方案--------------------
我在xcode5.1用控制台程序跑了你的程序,结果如下:
2014-03-24 18:59:20.016 qwe[4854:303] ------ 111111 ----- <TestObj: 0x100200340>
  相关解决方案