草庐IT

ios - Objective-C : Strange behavior when using NSString and __weak with ARC

coder 2023-09-23 原文

第一个代码和输出:

NSString *text = @"Sunny";
__weak NSString *string0 = text.lowercaseString;
__weak NSString *string1;
string1 = text.lowercaseString;

NSLog(@"%@, %@", string0, string1);

输出:

(null), sunny

但是当我将 string1 的声明移到 text 上方后,输出是不同的。这是代码:

__weak NSString *string1;
NSString *text = @"Sunny";
__weak NSString *string0 = text.lowercaseString;
string1 = text.lowercaseString;

NSLog(@"%@, %@", string0, string1);

输出:

sunny, sunny

我对不同的输出感到很困惑:

  • 为什么 string0string1 在第一种情况下不同?
  • 为什么第二种情况的输出与第一种不同?

最佳答案

试图弄清楚对象何时被释放或弱引用何时被清空可能具有挑战性,而且通常无助于理解。以下是您看到的结果与预期不同的一些原因:

  • NSString :在进行此类调查时,最好永远不要使用这种类型。字符串文字是不朽的,它们不会被收集,即使您不希望有字符串文字,您也可能拥有一个字符串文字。
  • 自动释放池:自动释放池确实是 ARC 之前时代的遗留物,但它仍然存在并且许多方法返回自动释放的对象。这意味着许多对象的生命周期会比您预期的要长,但不会太长。然而 ARC 有技巧,可以提前从自动释放池中删除对象,因此您可能首先认为对象会存活更长时间,然后它不会...
  • weak 引用:在前两个项目符号之后,您应该猜到,因为您可能不知道对象何时被释放,如果有的话,那么您可能不知道 weak 何时被释放。引用无效。想想“很快”。
  • 优化:编译器可以进行一些优化,在保留程序正确语义的同时,可能会改变对象的生命周期。

如果您确实想进行此类调查,那么如果 (a) 使用您自己的类类型,而不是库中的任何类型,并且 (b) 使用 @autoreleasepool { ... },您可能会取得进一步的进展 block 来限制自动释放对象的生命周期。

例如,当我在我使用的编译器上运行您的代码时,我没有得到 (null) , 但是将第一个分配更改为 string0 = text.lowercaseString.mutableCopy确实产生了一个......弄清楚为什么留下来作为练习......

有一颗探索的心和探索的心,这很好,但要为不明显的事情做好准备!

HTH

关于ios - Objective-C : Strange behavior when using NSString and __weak with ARC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31529954/

有关ios - Objective-C : Strange behavior when using NSString and __weak with ARC的更多相关文章

  1. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  2. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  3. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  4. objective-c - 在设置 Cocoa Pods 和安装 Ruby 更新时出错 - 2

    我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U

  5. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  6. ruby - 为 IO::popen 拯救 "command not found" - 2

    当我将IO::popen与不存在的命令一起使用时,我在屏幕上打印了一条错误消息:irb>IO.popen"fakefake"#=>#irb>(irb):1:commandnotfound:fakefake有什么方法可以捕获此错误,以便我可以在脚本中进行检查? 最佳答案 是:升级到ruby​​1.9。如果您在1.9中运行它,则会引发Errno::ENOENT,您将能够拯救它。(编辑)这是在1.8中的一种hackish方式:error=IO.pipe$stderr.reopenerror[1]pipe=IO.popen'qwe'#

  7. objective-c - 将 Cocoa header 链接到 ruby​​ C 扩展 - 2

    我正在为ruby​​开发一个C扩展,但我需要包含来自IOBluetooth框架的header,特别是:#import#import一切都编译正常,但在运行时,扩展错误:path/to/file.rb:1:in`require_relative':dlopen(/path/to/extension.bundle,9):Symbolnotfound:_OBJC_CLASS_$_IOBluetoothDeviceInquiry(LoadError)我相当确定这与未包含在链接过程中的框架有关,但我不确定原因。任何帮助将不胜感激extconf.rb:#Loadsmkmfwhichisusedto

  8. ruby - IO::EAGAINWaitReadable:资源暂时不可用 - 读取会阻塞 - 2

    当我尝试使用“套接字”库中的方法“read_nonblock”时出现以下错误IO::EAGAINWaitReadable:Resourcetemporarilyunavailable-readwouldblock但是当我通过终端上的IRB尝试时它工作正常如何让它读取缓冲区? 最佳答案 IgetthefollowingerrorwhenItrytousethemethod"read_nonblock"fromthe"socket"library当缓冲区中的数据未准备好时,这是预期的行为。由于异常IO::EAGAINWaitReadab

  9. ruby - 如何使用 ruby​​ fibers 避免阻塞 IO - 2

    我需要将目录中的一堆文件上传到S3。由于上传所需的90%以上的时间都花在了等待http请求完成上,所以我想以某种方式同时执行其中的几个。Fibers能帮我解决这个问题吗?它们被描述为解决此类问题的一种方法,但我想不出在http调用阻塞时我可以做任何工作的任何方法。有什么方法可以在没有线程的情况下解决这个问题? 最佳答案 我没有使用1.9中的纤程,但是1.8.6中的常规线程可以解决这个问题。尝试使用队列http://ruby-doc.org/stdlib/libdoc/thread/rdoc/classes/Queue.html查看文

  10. ruby - 如何从 ruby​​ 中的 IO 对象获取文件名 - 2

    在ruby中...我有一个由外部进程创建的IO对象,我需要从中获取文件名。然而我似乎只能得到文件描述符(3),这对我来说不是很有用。有没有办法从此对象获取文件名甚至获取文件对象?我正在从通知程序中获取IO对象。所以这也可能是获取文件路径的一种方式? 最佳答案 关于howtogetathefilenameinC也有类似的问题,我将在这里以ruby​​的方式给出这个问题的答案。在Linux中获取文件名假设io是您的IO对象。以下代码为您提供了文件名。File.readlink("/proc/self/fd/#{io.fileno}")例

随机推荐