1)禁用ARC。
2)我有以下代码:
- (IBAction)btnsecondClicked:(id)sender {
NSString *myname;
myname = retrieveName();
}
NSString * retrieveName()
{
NSString *tmpStr = [[NSString alloc] initWithString "StackOverFlow"];
return tmpStr;
}
我尝试使用Analyzer,它说
"对象泄漏:以后在此执行路径中未引用已分配的对象并具有 保留计数为+ 1"
指向调用retrieName
的行旁边的行。
我的问题:
对象的保留计数是多少?不应该是2?
,因为:
第一个引用计数位于retrieveName()
2.第二个计数是btnsecondClicked()
,myname
变量在哪里?
ie:myname = retrievedName ()
- >它不会增加引用次数吗?
答案 0 :(得分:2)
在此步骤中,您已创建字符串NSString *tmpStr = [[NSString alloc] initWithString "StackOverFlow"];
。因此,您已经+1引用计数,因为始终alloc:
会返回+1计数的对象。然后你会在哪里发布这个?这就是它显示泄漏的原因。
答案 1 :(得分:1)
从所有权的角度思考 - 专注于您想要说的语义,而不是实现的编写方式。这是面向对象的编程。
任何调用alloc
的人都会获得拥有的参考资料。任何打电话给retain
的人都会建立所有权。因此,每次调用alloc或retain都必须匹配一个版本 - 如果您希望自动处理,则可以立即匹配release
或autorelease
。
堆栈上结果的标准是自动释放。这甚至体现在工厂方法(例如[NSString +string]
)返回这种非拥有参考的规则中。
答案 2 :(得分:1)
不,因为传递一个对象不会对保留计数添加任何内容。
但是,如果你做了
- (IBAction)btnsecondClicked:(id)sender {
NSString *myname;
myname = [retrieveName() retain];
}
然后保留计数将增加到2,因为您明确声明了对该特定对象的所有权。
答案 3 :(得分:1)
- (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
}