【发布时间】:2020-04-07 16:55:59
【问题描述】:
在设置作为输入指针的变量时,我对 ARC 的行为有点困惑,并且预计在函数范围之外仍然有效。
考虑以下使用 openDirectory 框架的示例。
@interface bbb
-(bool)doSomethingWithADRecord:
-(void)obtainADRecord(NSString*)user
-(NSString*)getADrecord:(ODAttributeType)attr fromRecord:(ODRecord*)record;
@end
@interface bbb {
ODRecord *_myRecord;
}
@end
@implementation bbb
-(void)doSomethingWithADRecord:
{
// here we access _myRecord and expect it to be valid.
}
-(bool)obtainADRecord:(NSString*)user
{
...
// here I call the method that will set the member _myRecord from type ODRecord*
// whose scope related to the lifespan of the containing class (bbb)
[self getADrecord:attr toRecord:_myRecord];
}
// the following function should set the variable record to be used by the caller.
-(NSString*)getADrecord:(ODAttributeType)attr fromRecord:(ODRecord*)record {
...
// here a set an ODQuery object.
ODQuery *query = [[ODQuery alloc] initWithNode ...
// queryResults is an array of items from type ODQuery*
NSArray* queryResults = [query resultsAllowingPartial:NO error:&err];
for(ODRecord *item in queryResults) {
if (/*some logic*/)
{
//option 1: just regular set operator, expecting the ARC will do the retain itself
record = item;
//option 2: explicits take a reference on that item.
record = [[item retain] autorelease];
return @"found item";
}
}
}
@end
为了澄清我的问题,我想知道我上面提到的 2 个选项中的哪一个是正确的,将引用传递给 record 并最终传递给 _myRecord,因此它将存储正确的值即使在queryResults 的临时列表将被清理之后。
请注意,在这两个选项中,我只是设置了指针值,而没有从 ODquery 类型启动新对象并将数据复制到这个新对象。
谢谢!
【问题讨论】:
-
如果说
[[item retain] autorelease];编译,你根本没有使用ARC。那么问题是什么? -
@matt,我想知道简单地执行
record = item是否足以使该对象指向的数据持续超出函数getADrecord的范围。因为如果在没有智能指针的情况下使用 c/c++,在这种情况下我可能最终会出现悬空指针。我希望我现在澄清了我的观点 -
我再说一遍。如果
retain编译,则整个文件的 ARC 都关闭。这意味着您的所有代码都是错误的,除非您始终自己管理内存。 -
@Matt,好的,感谢您澄清这一点。所以我会放弃这个选项,因为我想避免自己处理内存管理。所以这给我留下了
record = item的第 1 个选项,但它会在离开函数时传递对_myRecord的引用吗? -
没关系!如果您正在使用 ARC,甚至不要考虑内存管理的作用。只需编写代码并相信 ARC 会做正确的事。这就是 ARC 的意思:它是自动的。这就是为什么我建议整个问题毫无意义。
标签: objective-c pointers automatic-ref-counting indirection