OSX上的Delphi XE6 ARC发布变量 [英] Delphi XE6 ARC on OSX releasing variables

查看:138
本文介绍了OSX上的Delphi XE6 ARC发布变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在不期望的时候释放了NSObject实例时遇到了问题.我有一个类型为NSNumber的表单变量,在button1中,我创建了一个实例并设置了一个值,在button2中,我读取了该值.如果我没有在按钮1中调用保留",则该变量将被释放,并且当我单击按钮2"时,应用将挂起,添加一个保留调用将使所有工作正常.

I'm having a problem with NSObject instances being freed when I don't expect. I have a form variable of type NSNumber, in button1 I create an instance and set a value, in button2 I read the value. If I don't call retain in button 1 then the variable is freed and the app hangs when I click button2, adding a call to retain makes everything work.

这是在OSX上使用带有Firemonkey的Delphi XE6.

This is on OSX using Delphi XE6 with firemonkey.

这是一些代码

定义类型为NSNumber的表单变量

Define a form variable of type NSNumber

Fv : NSNumber;

现在添加几个按钮

对于Button1Click

for Button1Click

begin
  Fv := TNSNumber.Wrap(TNSNumber.OCClass.numberWithFloat(4.0));
  ShowMessage(IntToStr(Fv.retainCount)); // value is 1
  Fv.retain; // comment out this to make it crash on button2 click
  ShowMessage(IntToStr(Fv.retainCount)); // value is 2, or 1 without the retain
end;

对于Button2click

for Button2click

begin
   ShowMessage(IntToStr(Fv.retainCount)); // value is 1 or crashes without the retain
 ShowMessage(FloatToStr(Fv.doubleValue));
end;

现在似乎正在发生的事情是在Button1单击结束时,delphi通过减少引用计数来释放Fv-即它的作用就像超出范围.因此,要使Fv徘徊,我必须添加Fv.retain.如果我单击没有保留的button2,则会崩溃.

Now what seems to be happening is at the end of Button1 click, delphi is releasing Fv by decrementing the reference count - i.e. it acts like its going out of scope. So to make Fv hang around I have to add the Fv.retain. If I click button2 without the retain, then it crashes.

我应该保留吗-我认为没有必要,或者我还有其他遗漏吗?

Should I put a retain in - I didn't think it was necessary, or am I missing something else?

tia

推荐答案

感谢@RudyVelthius和@RemyLebeau使我走上了正确的道路.

Thanks to @RudyVelthius and @RemyLebeau for putting me on the right path.

问题不是德尔福问题,而是目标C问题(至少我对目标C的理解是问题).

The problem isn't a delphi problem but an objective C problem (at least my understanding of objective C is the problem).

TNSNumber.OCClass.numberWithFloat(4.0)

是一种便捷的构造方法-这意味着它已添加到自动释放池中,并在下次主运行循环执行时释放.

is a convenience constructor - this means its added to the auto release pool, and freed next time the main run loop executes.

所以我的delphi界面很好,但不幸的是,它指向的东西不再存在.要在通话保留周围保留自动释放变量.只是为了证明这是调用alloc/init应该解决的问题.所以

So my delphi interface is fine, but unfortunately it's pointing to something thats no longer there. To keep an autorelease variable around call retain. Just to prove this is the problem calling alloc/init should fix it. so

替换

Fv := TNSNumber.Wrap(TNSNumber.OCClass.numberWithFloat(4.0));

使用

Fv := TNSNumber.Wrap(TNSNumber.Alloc.initWithDouble(4.0));

并移除保留物,一切正常.

and remove the retain and it all works.

从此处 https://stackoverflow.com/a/801000/416047 规则是

如果返回对象的选择器的单词为"new","alloc", 在其中保留"或复制",则您拥有返回的对象并且是 完成后负责释放它.

If the selector returning an object has the word "new", "alloc", "retain" or "copy" in it, then you own the returned object and are responsible for releasing it when you are finished.

否则,您将不拥有它,也不应释放它.如果你想 保留对非拥有对象的引用,应调用-[NSObject 保留].您现在拥有"该实例是必须的 因此,完成后在实例上调用-[NSObject release] 用它.因此,您不拥有-[NSNumber返回的实例 numberWithInt:],并且在完成后不应在其上调用-release. 如果要将返回的实例保留在当前范围之外 (确实超出了当前NSAutoreleasePool的生命周期 实例),则应-保留它.

Otherwise you do not own it and should not release it. If you want to keep a reference to a non-owned object, you should call -[NSObject retain] on that instance. You now "own" that instance an must therefore call -[NSObject release] on the instance when you are done with it. Thus you do not own the instance returned by -[NSNumber numberWithInt:] and should not call -release on it when you are done. If you want to keep the returned instance beyond the current scope (really beyond the lifetime of the current NSAutoreleasePool instance), you should -retain it.

这篇关于OSX上的Delphi XE6 ARC发布变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆