我有一些代码可以为 UIView 设置动画:在沿路径设置动画的同时将其缩小。
它因以下错误而崩溃(可重现:总是):
CoreGraphics`CG::Path::apply(void*, void (*)(void*, CGPathElementType, CGPoint const*)) const:
0x1055c06: pushl %ebp
0x1055c07: movl %esp, %ebp
0x1055c09: subl $24, %esp
0x1055c0c: movl 8(%ebp), %eax
0x1055c0f: movl (%eax), %ecx
0x1055c11: movl (%ecx), %eax
0x1055c13: movl 16(%ebp), %edx
0x1055c16: movl %edx, 8(%esp)
0x1055c1a: movl 12(%ebp), %edx
0x1055c1d: movl %edx, 4(%esp)
0x1055c21: movl %ecx, (%esp)
0x1055c24: calll *64(%eax)
0x1055c27: addl $24, %esp
0x1055c2a: popl %ebp
0x1055c2b: ret
我认为它来自下面的方法(pathAnimationWithStartPoint:),好像我没有添加它返回的 CAKeyframeAnimation,即,只是:
[group setAnimations:@[ zoomAnimation ]];
代替
[group setAnimations:@[ zoomAnimation, pathAnimation ]];
它运行时不会崩溃。
- (CAKeyframeAnimation *) pathAnimationWithStartPoint:(CGPoint) startPoint {
CGPoint endPoint = self.showApplicationTourButton.center;
CGFloat xDistanceBetweenStartAndEndPoints = abs(startPoint.x - endPoint.x);
CGFloat yOfHighestPointOfCurvePath = endPoint.y - 250;
CGPoint controlPoint1 = CGPointMake(startPoint.x + 1.0f / 3.0f * xDistanceBetweenStartAndEndPoints, yOfHighestPointOfCurvePath);
CGPoint controlPoint2 = CGPointMake(startPoint.x + 2.0f / 3.0f * xDistanceBetweenStartAndEndPoints, yOfHighestPointOfCurvePath);
CGMutablePathRef curvedPath = CGPathCreateMutable();
CGPathMoveToPoint(curvedPath, NULL, startPoint.x, startPoint.y);
CGPathAddCurveToPoint(curvedPath, NULL, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, endPoint.x, endPoint.y);
CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
pathAnimation.path = curvedPath;
CGPathRelease(curvedPath);
pathAnimation.calculationMode = kCAAnimationPaced;
pathAnimation.fillMode = kCAFillModeForwards;
pathAnimation.removedOnCompletion = NO;
return pathAnimation;
}
回溯:
* thread #1: tid = 0x1a03, 0x01055c11 CoreGraphics`CG::Path::apply(void*, void (*)(void*, CGPathElementType, CGPoint const*)) const + 11, stop reason = EXC_BAD_ACCESS (code=2, address=0x0)
frame #0: 0x01055c11 CoreGraphics`CG::Path::apply(void*, void (*)(void*, CGPathElementType, CGPoint const*)) const + 11
frame #1: 0x00f5d090 CoreGraphics`CGPathApply + 64
frame #2: 0x01838c68 QuartzCore`CA::Render::Path::new_path(CGPath const*, bool) + 158
frame #3: 0x018c3493 QuartzCore`-[CAKeyframeAnimation _setCARenderAnimation:layer:] + 176
frame #4: 0x018c3b2c QuartzCore`-[CAKeyframeAnimation _copyRenderAnimationForLayer:] + 68
frame #5: 0x018c6f12 QuartzCore`-[CAAnimationGroup _copyRenderAnimationForLayer:] + 241
frame #6: 0x018df547 QuartzCore`CA::Layer::commit_animations(CA::Transaction*, double (*)(CA::Layer*, double, void*), void (*)(CA::Layer*, CA::Render::Animation*, void*), void (*)(CA::Layer*, void**, void*), void*) + 641
frame #7: 0x01855520 QuartzCore`CA::Context::commit_layer(CA::Layer*, unsigned int, unsigned int, void*) + 94
frame #8: 0x018d87fa QuartzCore`CA::Layer::commit_if_needed(CA::Transaction*, void (*)(CA::Layer*, unsigned int, unsigned int, void*), void*) + 330
frame #9: 0x018d877e QuartzCore`CA::Layer::commit_if_needed(CA::Transaction*, void (*)(CA::Layer*, unsigned int, unsigned int, void*), void*) + 206
frame #10: 0x01856667 QuartzCore`CA::Context::commit_transaction(CA::Transaction*) + 1775
frame #11: 0x01857227 QuartzCore`CA::Transaction::commit() + 395
frame #12: 0x018f9b17 QuartzCore`+[CATransaction commit] + 52
frame #13: 0x000399bf MyApp`-[HomeViewController catchTourScrollViewScreenshotViewAndAnimateItToButton](self=0x0b4e5210, _cmd=0x006f381a) + 1903 at HomeViewController.m:197
frame #14: 0x0391f663 libobjc.A.dylib`-[NSObject performSelector:] + 62
frame #15: 0x0003c383 MyApp`-[NSObject(self=0x0b4e5210, _cmd=0x006ef5ad, selector=0x006f381a) performSelectorIfRespondsToIt:] + 243 at NSObject+PerformSelectorIfRespondsToIt.m:22
frame #16: 0x00042506 MyApp`__44-[TourViewController closeTourWithAnimation]_block_invoke268(.block_descriptor=0x0b6985a0, finished='\x01') + 86 at TourViewController.m:419
frame #17: 0x01af0df6 UIKit`-[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] + 223
frame #18: 0x01ae3d66 UIKit`-[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 237
frame #19: 0x01ae3f04 UIKit`-[UIViewAnimationState animationDidStop:finished:] + 68
frame #20: 0x12b6ff28 UIKit`-[UIViewAnimationStateAccessibility(SafeCategory) animationDidStop:finished:] + 66
frame #21: 0x018df7d8 QuartzCore`CA::Layer::run_animation_callbacks(void*) + 284
frame #22: 0x03a90014 libdispatch.dylib`_dispatch_client_callout + 14
frame #23: 0x03a807d5 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 296
frame #24: 0x03f3eaf5 CoreFoundation`__CFRunLoopRun + 1925
frame #25: 0x03f3df44 CoreFoundation`CFRunLoopRunSpecific + 276
frame #26: 0x03f3de1b CoreFoundation`CFRunLoopRunInMode + 123
frame #27: 0x044c67e3 GraphicsServices`GSEventRunModal + 88
frame #28: 0x044c6668 GraphicsServices`GSEventRun + 104
frame #29: 0x01aa5ffc UIKit`UIApplicationMain + 1211
frame #30: 0x0000285d MyApp`main(argc=1, argv=0xbffff3f4) + 141 at main.m:16
frame #31: 0x00002785 MyApp`start + 53
* thread #1: tid = 0x1a03, 0x01055c11 CoreGraphics`CG::Path::apply(void*, void (*)(void*, CGPathElementType, CGPoint const*)) const + 11, stop reason = EXC_BAD_ACCESS (code=2, address=0x0)
frame #0: 0x01055c11 CoreGraphics`CG::Path::apply(void*, void (*)(void*, CGPathElementType, CGPoint const*)) const + 11
frame #1: 0x00f5d090 CoreGraphics`CGPathApply + 64
frame #2: 0x01838c68 QuartzCore`CA::Render::Path::new_path(CGPath const*, bool) + 158
frame #3: 0x018c3493 QuartzCore`-[CAKeyframeAnimation _setCARenderAnimation:layer:] + 176
frame #4: 0x018c3b2c QuartzCore`-[CAKeyframeAnimation _copyRenderAnimationForLayer:] + 68
frame #5: 0x018c6f12 QuartzCore`-[CAAnimationGroup _copyRenderAnimationForLayer:] + 241
frame #6: 0x018df547 QuartzCore`CA::Layer::commit_animations(CA::Transaction*, double (*)(CA::Layer*, double, void*), void (*)(CA::Layer*, CA::Render::Animation*, void*), void (*)(CA::Layer*, void**, void*), void*) + 641
frame #7: 0x01855520 QuartzCore`CA::Context::commit_layer(CA::Layer*, unsigned int, unsigned int, void*) + 94
frame #8: 0x018d87fa QuartzCore`CA::Layer::commit_if_needed(CA::Transaction*, void (*)(CA::Layer*, unsigned int, unsigned int, void*), void*) + 330
frame #9: 0x018d877e QuartzCore`CA::Layer::commit_if_needed(CA::Transaction*, void (*)(CA::Layer*, unsigned int, unsigned int, void*), void*) + 206
frame #10: 0x01856667 QuartzCore`CA::Context::commit_transaction(CA::Transaction*) + 1775
frame #11: 0x01857227 QuartzCore`CA::Transaction::commit() + 395
frame #12: 0x018f9b17 QuartzCore`+[CATransaction commit] + 52
frame #13: 0x000399bf MyApp`-[HomeViewController catchTourScrollViewScreenshotViewAndAnimateItToButton](self=0x0b4e5210, _cmd=0x006f381a) + 1903 at HomeViewController.m:197
frame #14: 0x0391f663 libobjc.A.dylib`-[NSObject performSelector:] + 62
frame #15: 0x0003c383 MyApp`-[NSObject(self=0x0b4e5210, _cmd=0x006ef5ad, selector=0x006f381a) performSelectorIfRespondsToIt:] + 243 at NSObject+PerformSelectorIfRespondsToIt.m:22
frame #16: 0x00042506 MyApp`__44-[TourViewController closeTourWithAnimation]_block_invoke268(.block_descriptor=0x0b6985a0, finished='\x01') + 86 at TourViewController.m:419
frame #17: 0x01af0df6 UIKit`-[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] + 223
frame #18: 0x01ae3d66 UIKit`-[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 237
frame #19: 0x01ae3f04 UIKit`-[UIViewAnimationState animationDidStop:finished:] + 68
frame #20: 0x12b6ff28 UIKit`-[UIViewAnimationStateAccessibility(SafeCategory) animationDidStop:finished:] + 66
frame #21: 0x018df7d8 QuartzCore`CA::Layer::run_animation_callbacks(void*) + 284
frame #22: 0x03a90014 libdispatch.dylib`_dispatch_client_callout + 14
frame #23: 0x03a807d5 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 296
frame #24: 0x03f3eaf5 CoreFoundation`__CFRunLoopRun + 1925
frame #25: 0x03f3df44 CoreFoundation`CFRunLoopRunSpecific + 276
frame #26: 0x03f3de1b CoreFoundation`CFRunLoopRunInMode + 123
frame #27: 0x044c67e3 GraphicsServices`GSEventRunModal + 88
frame #28: 0x044c6668 GraphicsServices`GSEventRun + 104
frame #29: 0x01aa5ffc UIKit`UIApplicationMain + 1211
frame #30: 0x0000285d MyApp`main(argc=1, argv=0xbffff3f4) + 141 at main.m:16
frame #31: 0x00002785 MyApp`start + 53
打开 NSZombie 不会提供任何更有用的调试信息。
在升级到 Xcode 4.6.3 (4H1503) 之前使用的相同代码。需要注意的是:在模拟器中,动画有时会暂停,点击它会恢复。这个奇怪的人工制品是出现问题的迹象,但我当时还不知道。
我错过了什么吗?
如果这是一个已知的错误,是否有任何解决方法?
一些研究笔记: similar question has been asked on SO ,但接受的答案只是通过将路径动画更改为线性平移来“解决”问题。
我的问题似乎也与此处的博文非常相似:http://www.blogosfera.co.uk/2013/08/exc_bad_access-while-using-coreanimation/
最佳答案
这真的不是什么答案,更多的是试图给你一个工具来寻找更多的线索。希望比我有更多线索的人会插话。
如果任一事件的最后一个事件是 FREE,则数据缓冲区(或对象)将被过早释放。 (有关获取 malloc 历史记录的信息,请参阅 http://lldb.llvm.org/lldb-gdb.html)。
现在,即使它确认这是一个过早的释放,它实际上可能不会帮助您那个。如果是这样,它会告诉你这是一个竞争条件。不幸的是,修复它实际上是不可能的,但可能有一种解决方法。如果您能弄清楚您控制的哪个对象可能已经分配了过早的 free()d 缓冲区,那么您应该能够持有对所述对象的强引用,直到动画完全完成。
请提交错误,附上崩溃的二进制文件。
此外,打开 malloc scribble。这将确保释放的内存在释放后立即被丢弃,这应该使崩溃尽快发生。
关于ios - 在 CAKeyframeAnimation 中崩溃,用于沿路径对 View 进行动画处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18448106/
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少
这是一道面试题,我没有答对,但还是很好奇怎么解。你有N个人的大家庭,分别是1,2,3,...,N岁。你想给你的大家庭拍张照片。所有的家庭成员都排成一排。“我是家里的friend,建议家庭成员安排如下:”1岁的家庭成员坐在这一排的最左边。每两个坐在一起的家庭成员的年龄相差不得超过2岁。输入:整数N,1≤N≤55。输出:摄影师可以拍摄的照片数量。示例->输入:4,输出:4符合条件的数组:[1,2,3,4][1,2,4,3][1,3,2,4][1,3,4,2]另一个例子:输入:5输出:6符合条件的数组:[1,2,3,4,5][1,2,3,5,4][1,2,4,3,5][1,2,4,5,3][