提问人:Whoami 提问时间:7/19/2014 最后编辑:BinarianWhoami 更新时间:7/19/2014 访问量:86
以下程序中对象的引用计数是多少?
What is the reference count of an object in the following program?
问:
1) 禁用 ARC。
2) 我有以下代码:
- (IBAction)btnsecondClicked:(id)sender {
NSString *myname;
myname = retrieveName();
}
NSString * retrieveName()
{
NSString *tmpStr = [[NSString alloc] initWithString "StackOverFlow"];
return tmpStr;
}
我尝试使用分析仪,它说
“对象泄漏:分配的对象稍后不会在此执行路径中引用,并且具有 保留计数为 +1”
指向调用的行旁边的行。retrieName
我的问题:
对象的保留计数是多少?不应该是 2 吗?
因为:
第一个引用计数在
retrieveName()
2.第二个计数在 中,其中变量成立?
btnsecondClicked()
myname
即: -> 它不会增加引用计数吗?
myname = retrievedName ()
答:
2赞
Mani
7/19/2014
#1
在此步骤中,您已经创建了字符串。所以你有 +1 个引用计数,因为总是返回 +1 计数的对象。那你将在哪里发布这个?这就是为什么它显示为泄漏。NSString *tmpStr = [[NSString alloc] initWithString "StackOverFlow"];
alloc:
1赞
Tommy
7/19/2014
#2
从所有权的角度思考——专注于你想说的话的语义,而不是实现的编写方式。这是面向对象的编程。
无论谁来电,都会得到一个拥有的参考。任何打电话的人都会建立所有权。因此,对 alloc 或 retain 的每个调用都必须与发布相匹配 - 无论是 immediate 还是 an (如果您希望它自主处理)。alloc
retain
release
autorelease
堆栈上结果的规范是自动发布。这甚至被载入了工厂方法(例如 返回这样一个非拥有引用。[NSString +string]
1赞
galrito
7/19/2014
#3
否,因为传递对象不会对保留计数增加任何内容。
但是,如果你这样做了
- (IBAction)btnsecondClicked:(id)sender {
NSString *myname;
myname = [retrieveName() retain];
}
然后,保留计数将增加到 2,因为您显式声明了该特定对象的所有权。
1赞
Basheer_CAD
7/19/2014
#4
- (IBAction)btnsecondClicked:(id)sender {
NSString *myname; // nil object, no retain count
myname = retrieveName(); // we received the object with retain count 1 (not 2 because you are not sending `retain` to the received object)
} // you exited the function without having global reference on the object, mynames is lost because it was created inside the function, i.e. you leaked at this step
NSString * retrieveName()
{
NSString *tmpStr = [[NSString alloc] initWithString "StackOverFlow"]; // retain count is 1
return tmpStr; // tmpStr returned with retain count of 1
}
现在这里是修复的代码
- (IBAction)btnsecondClicked:(id)sender {
NSString *myname;
myname = retrieveName(); // retain count = 1 and the object is the autorelease pool
}// you exited the function, autorelease pool automatically drained, the object is released, no leak
NSString * retrieveName()
{
NSString *tmpStr = [[NSString alloc] initWithString "StackOverFlow"];
return [tmpStr autorelease]; // the object with retain count=1, and added to releasePool
}
评论
autorelease
tmpStr
retrieveName