草庐IT

ios - 在 SKScene 的子节点上运行一个简单的操作会导致 iOS 7.1 中的 EXC_BAD_ACCESS

coder 2023-09-29 原文

在对我一直在开发的 SpriteKit 游戏进行最后润色时遇到了这个运行时错误。在 iOS 8 上运行良好,但在 iOS 7.1(模拟器和设备)上崩溃。

我创建了一个小项目,它重现了我正在处理的问题。它通过解压缩在 Xcode 6 中提供的编辑器中创建的 sks 文件来创建一个 GameScene(就像创建新的 SpriteKit 项目时生成的示例项目一样)。使用 childNodeWithName: 在生成的场景中获取对 sprite 的引用后,尝试对其运行简单操作会使程序崩溃并引发 EXC_BAD_ACCESS。直接修改 Sprite 的属性似乎工作正常(见代码)。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    /* Called when a touch begins */

    for (UITouch *touch in touches) {
        CGPoint location = [touch locationInNode:self];

        SKSpriteNode *sprite = (SKSpriteNode*)[self childNodeWithName:@"sprite"];

        // This works.
        sprite.position = location;

        SKAction *action = [SKAction moveByX:100 y:0 duration:1];

        // This doesn't.
        [sprite runAction:action];
    }
}

我一直在搜索互联网和我自己的大脑,据我所知,我没有违反任何规则。请告诉我我错了,特别是我违反了哪条规则。因为如果事实证明这是一个不是我的错的问题,那么挫败感会大得多。我在做一些 iOS 7 中不可用的事情吗?

注意:我对通用示例 SpriteKit 项目(Spaceship 项目)所做的唯一更改是我在 SKScene 编辑器中添加了一个普通的红色 Sprite ,并将其命名为“sprite”,并且修改 touchesBegan: 方法,如上所示。

另请注意:以编程方式添加 Sprite (如在示例项目中)不会引发此问题,使用 childNodeWithName: 获取对它的引用工作得很好.这个问题似乎只在访问存档的 sks 文件中包含的 Sprite 时出现。

这是崩溃时的痕迹:

* thread #1: tid = 0x4da6c, 0x00000000, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x00000000
frame #1: 0x009b65d7 SpriteKit`SKCSprite::update(double) + 231
frame #2: 0x009b66de SpriteKit`SKCSprite::update(double) + 494
frame #3: 0x0099bd58 SpriteKit`-[SKNode _update:] + 43
frame #4: 0x0097c003 SpriteKit`-[SKScene _update:] + 104
frame #5: 0x009919a4 SpriteKit`-[SKView(Private) _update:] + 253
frame #6: 0x0098f5e1 SpriteKit`-[SKView renderCallback:] + 936
frame #7: 0x0098cea0 SpriteKit`__29-[SKView setUpRenderCallback]_block_invoke + 82
frame #8: 0x009b168f SpriteKit`-[SKDisplayLink _callbackForNextFrame:] + 268
frame #9: 0x009b19ad SpriteKit`-[SKDisplayLink _caDisplayLinkCallback] + 137
frame #10: 0x048cdd66 QuartzCore`CA::Display::DisplayLinkItem::dispatch() + 48
frame #11: 0x048cdc22 QuartzCore`CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 310
frame #12: 0x048ce147 QuartzCore`CA::Display::TimerDisplayLink::callback(__CFRunLoopTimer*, void*) + 123
frame #13: 0x006d4ac6 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
frame #14: 0x006d44ad CoreFoundation`__CFRunLoopDoTimer + 1181
frame #15: 0x006bc538 CoreFoundation`__CFRunLoopRun + 1816
frame #16: 0x006bb9d3 CoreFoundation`CFRunLoopRunSpecific + 467
frame #17: 0x006bb7eb CoreFoundation`CFRunLoopRunInMode + 123
frame #18: 0x02b6a5ee GraphicsServices`GSEventRunModal + 192
frame #19: 0x02b6a42b GraphicsServices`GSEventRun + 104
frame #20: 0x00aa1f9b UIKit`UIApplicationMain + 1225
* frame #21: 0x00061a2d SKTest`main(argc=1, argv=0xbff9f39c) + 141 at main.m:14
frame #22: 0x027606d9 libdyld.dylib`start + 1

最佳答案

我遇到了这个问题,这是我黑进的解决方法。是的,这并不理想,但肯定能避免崩溃。

加载场景后复制 SKSPriteNode 并像这样交换新节点:

 SKSpriteNode *sprite = (SKSpriteNode*)[self childNodeWithName:@"bob"];
 SKSpriteNode *newSprite = [sprite copy];
 [sprite removeFromParent];
 [self addChild:newSprite];

现在,您可以在该新节点上访问并使用 SKAction,但是您喜欢使用 touchesBegan 方法中的相同代码。

我的猜测是基于 .sks 的节点的属性以某种方式无法正确初始化。

如果您有很多节点,您可能可以循环/枚举它们来进行这种交换。

更新

Original poster 更进一步,发现创建 GameScene 的副本也能达到目的。因此无需循环遍历节点并单独制作副本。

关于ios - 在 SKScene 的子节点上运行一个简单的操作会导致 iOS 7.1 中的 EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28521787/

有关ios - 在 SKScene 的子节点上运行一个简单的操作会导致 iOS 7.1 中的 EXC_BAD_ACCESS的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  3. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  4. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  5. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  6. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  7. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  8. 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返回它复制的字节数,但是当我还没有下

  9. ruby-on-rails - 无法让 rspec、spork 和调试器正常运行 - 2

    GivenIamadumbprogrammerandIamusingrspecandIamusingsporkandIwanttodebug...mmm...let'ssaaay,aspecforPhone.那么,我应该把“require'ruby-debug'”行放在哪里,以便在phone_spec.rb的特定点停止处理?(我所要求的只是一个大而粗的箭头,即使是一个有挑战性的程序员也能看到:-3)我已经尝试了很多位置,除非我没有正确测试它们,否则会发生一些奇怪的事情:在spec_helper.rb中的以下位置:require'rubygems'require'spork'

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

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

随机推荐