草庐IT

关于macos:Delphi XE6 ARC on OSX 发布变量

codeneng 2023-03-28 原文

Delphi XE6 ARC on OSX releasing variables

当我没想到时,我遇到了 NSObject 实例被释放的问题。我有一个 NSNumber 类型的表单变量,在 button1 中创建一个实例并设置一个值,在 button2 中读取该值。如果我不在按钮 1 中调用保留,那么当我单击按钮 2 时,变量被释放并且应用程序挂起,添加对保留的调用使一切正常。

这是在 OSX 上使用 Delphi XE6 和 firemonkey。

这是一些代码

定义一个 NSNumber 类型的表单变量

1
Fv : NSNumber;

现在添加几个按钮

对于 Button1Click

1
2
3
4
5
6
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

1
2
3
4
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,那么它会崩溃。

我应该添加一个保留 - 我认为没有必要,还是我错过了其他东西?

tia

  • 以 iOS 为目标时也会发生同样的事情。当我package Objective-C 对象时,我有时必须调用 retain,有时不需要。还没有弄清楚有什么区别-但是很容易检测到何时需要保留:-)
  • 我不知道 XE 6 的 OS X 编译器实现了 ARC。我以为只有iOS和Android?
  • FWIW,numberWithFloat() 可能会生成一个自动释放变量(大多数"便利构造函数"都会这样做)。这些确实必须保留,以使它们比下一个自动释放周期运行更长时间。
  • @RudyVelthuis:Delphi 仅在 iOS 和 Android 上使用对象 ARC。但是,Delphi 与 OSX/iOS/Android 上的本机平台 API 交互的桥接框架确实使用接口。在这种情况下,Macapi.Foundation.pas 中的 type NSNumber = interface(NSValue)
  • @RudyVelthuis 回复:OSX 上的 ARC,是的,我认为是这种情况,但各种文档到处都说矛盾的东西,所以不太正如雷米勒博所说。虽然我不确定为什么当变量仍在范围内时会释放接口。


感谢@RudyVelthius 和@RemyLebeau 让我走上了正确的道路。

问题不是delphi问题,而是客观C问题(至少我对objective C的理解是问题)。

1
TNSNumber.OCClass.numberWithFloat(4.0)

是一个方便的构造函数 - 这意味着它被添加到自动释放池中,并在下次主运行循环执行时释放。

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

替换

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

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

并删除保留,一切正常。

从这里 https://stackoverflow.com/a/801000/416047 规则是

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.

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.

有关关于macos:Delphi XE6 ARC on OSX 发布变量的更多相关文章

  1. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  2. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  3. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  4. ruby-on-rails - 使用 ruby​​ 将多个实例变量转换为散列的更好方法? - 2

    我收到格式为的回复#我需要将其转换为哈希值(针对活跃商家)。目前我正在遍历变量并执行此操作:response.instance_variables.eachdo|r|my_hash.merge!(r.to_s.delete("@").intern=>response.instance_eval(r.to_s.delete("@")))end这有效,它将生成{:first="charlie",:last=>"kelly"},但它似乎有点hacky和不稳定。有更好的方法吗?编辑:我刚刚意识到我可以使用instance_variable_get作为该等式的第二部分,但这仍然是主要问题。

  5. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  6. ruby - Rack:如何将 URL 存储为变量? - 2

    我正在编写一个简单的静态Rack应用程序。查看下面的config.ru代码:useRack::Static,:urls=>["/elements","/img","/pages","/users","/css","/js"],:root=>"archive"map'/'dorunProc.new{|env|[200,{'Content-Type'=>'text/html','Cache-Control'=>'public,max-age=6400'},File.open('archive/splash.html',File::RDONLY)]}endmap'/pages/search.

  7. ruby-on-rails - 如何在发布新的 Ruby 或 Rails 版本时收到通知? - 2

    有人知道在发布新版本的Ruby和Rails时收到电子邮件的方法吗?他们有邮件列表,RubyonRails有一个推特,但我不想听到那些随之而来的喧嚣,我只想知道什么时候发布新版本,尤其是那些有安全修复的版本。 最佳答案 从therailsblog获取提要.http://weblog.rubyonrails.org/feed/atom.xml 关于ruby-on-rails-如何在发布新的Ruby或Rails版本时收到通知?,我们在StackOverflow上找到一个类似的问题:

  8. ruby-on-rails - 应用程序的名称是否可以作为变量使用? - 2

    当我创建一个Rails应用程序时,控制台:railsnewfoo我的代码可以使用字符串“foo”吗?puts"Yourapp'snameis"+app_name_bar 最佳答案 Rails.application.class将为您提供应用程序的全名(例如YourAppName::Application)。从那里您可以使用Rails.application.class.parent获取模块名称。 关于ruby-on-rails-应用程序的名称是否可以作为变量使用?,我们在StackOve

  9. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  10. ruby - 在 Ruby 中,在类方法的上下文中,什么是实例变量和类变量? - 2

    如果我有以下一段Ruby代码:classBlahdefself.bleh@blih="Hello"@@bloh="World"endend@blih和@@bloh到底是什么?@blih是Blah类中的一个实例变量,@@bloh是Blah类中的一个类变量,对吗?这是否意味着@@bloh是Blah的类Class中的一个变量? 最佳答案 人们似乎忽略了该方法是类方法。@blih将是常量Bleh的类Class实例的实例变量。因此:irb(main):001:0>classBlehirb(main):002:1>defself.blehirb

随机推荐