刚接触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); }