- objective-c - iOS 5 : Can you override UIAppearance customisations in specific classes?
- iphone - 如何将 CGFontRef 转换为 UIFont?
- ios - 以编程方式关闭标记的信息窗口 google maps iOS
- ios - Xcode 5 - 尝试验证存档时出现 "No application records were found"
我有一个 CADisplayLink 触发 Director 对象中的 draw
方法。我想使 CADisplayLink 无效,然后解除分配一些由 Director 对象使用的单例缓存对象。 draw
方法不保留单例缓存对象。
在 Director 中一个名为 stopAnimation
的方法中(此方法与 draw
方法无关),我这样做:
[displayLink invalidate];
然后我开始释放单例缓存对象,但随后 CADisplayLink 触发并且最后一次调用了 draw
方法。 draw
方法尝试访问已释放的单例对象,但一切都崩溃了。
这只是有时会发生:有时应用程序不会崩溃,因为缓存对象在 displayLink 实际上无效并且 draw 方法已经完成运行后被释放。
在使 displayLink 无效后,我如何检查 draw 方法是否已完成运行并且不会再次触发,以便安全地使 Cache 对象无效?如果可能,我不想修改 draw
方法。
我尝试了多种组合,包括在主线程上执行displayLink invalidate
[self performSelectorOnMainThread:@selector(stopAnimation) withObject:self waitUntilDone:YES]
或尝试在当前运行循环中使用
[[NSRunLoop currentRunLoop] performSelector:@selector(stopAnimation) target:self 参数:nil order:10 modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
但结果总是一样的,有时过早释放共享缓存。
我也不想使用具有任意延迟的 performSelector:withObject:afterDelay:
方法。我想确保 displayLink 无效,draw 方法结束,并且不会再次运行。
最佳答案
这可能有点晚了,但是因为没有答案......
我不认为,你的选择器被再次调用,而是显示链接的线程在你的绘制框架方法的中间。在任何情况下,问题都是一样的。这是多线程,尝试在一个线程中释放一些对象而在另一个线程中使用它们通常会导致冲突。
可能最简单的解决方案是在绘制框架方法中放置一个标志和一个“if 语句”作为
if(schaduledForDestruction) {
[self destroy];
return;
}
然后在任何使显示链接无效的地方将“schaduledForDestruction”设置为 YES。
如果您真的认为显示链接会再次调用此方法,您可以在那个“destructionInProgress”中使用另一个 if。
如果你不想改变绘制框架的方法,你可以尝试将一个新的选择器强制到显示链接...
CADisplayLink *myDisplayLink;
BOOL resourcesLoaded;
SEL drawSelector;
- (void)destroy {
if(resourcesLoaded) {
[myDisplayLink invalidate];
//free resources
resourcesLoaded = NO;
}
}
- (void)metaLevelDraw {
[self performSelector:drawSelector];
}
- (void)drawFrame {
//draw stuff
}
- (void)beginAnimationing {
drawSelector = @selector(drawFrame);
myDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(metaLevelDraw)];
[myDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
- (void)endAnimationing {
drawSelector = @selector(destroy);
}
或者只是考虑这样的事情(但我不能说这是安全的。如果新创建的显示链接可以在与原始线程不同的线程上运行选择器,那么它什么也解决不了)。
CADisplayLink *myDisplayLink;
BOOL resourcesLoaded;
- (void)destroy {
if(resourcesLoaded) {
[myDisplayLink invalidate];
//free resources
resourcesLoaded = NO;
}
}
- (void)drawFrame {
//draw stuff
}
- (void)beginAnimationing {
myDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawFrame)];
[myDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
- (void)endAnimationing {
[myDisplayLink invalidate];
myDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(destroy)];
[myDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
关于ios - CADisplayLink 目标选择器在失效后被触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6418876/
我之前让 dll 注入(inject)器变得简单,但我有 Windows 7,我用 C# 和 C++ 做了它,它工作得很好!但是现在当我在 Windows 8 中尝试相同的代码时,它似乎没有以正确的方
我正在尝试制作一个名为 core-splitter 的元素,该元素在 1.0 中已弃用,因为它在我们的项目中起着关键作用。 如果您不知道 core-splitter 的作用,我可以提供一个简短的描述。
我有几个不同的蜘蛛,想一次运行所有它们。基于 this和 this ,我可以在同一个进程中运行多个蜘蛛。但是,我不知道如何设计一个信号系统来在所有蜘蛛都完成后停止 react 器。 我试过了: cra
有没有办法在达到特定条件时停止扭曲 react 器。例如,如果一个变量被设置为某个值,那么 react 器应该停止吗? 最佳答案 理想情况下,您不会将变量设置为一个值并停止 react 器,而是调用
https://code.angularjs.org/1.0.0rc9/angular-1.0.0rc9.js 上面的链接定义了外部js文件,我不知道Angular-1.0.0rc9.js的注入(in
我正在尝试运行一个函数并将服务注入(inject)其中。我认为这可以使用 $injector 轻松完成.所以我尝试了以下(简化示例): angular.injector().invoke( [ "$q
在 google Guice 中,我可以使用函数 createInjector 创建基于多个模块的注入(inject)器。 因为我使用 GWT.create 在 GoogleGin 中实例化注入(in
我在 ASP.NET Core 1.1 解决方案中使用配置绑定(bind)。基本上,我在“ConfigureServices Startup”部分中有一些用于绑定(bind)的简单代码,如下所示: s
我在 Spring MVC 中设置 initBinder 时遇到一些问题。我有一个 ModelAttribute,它有一个有时会显示的字段。 public class Model { privat
我正在尝试通过jquery post发布knockoutjs View 模型 var $form = $('#barcodeTemplate form'); var data = ko.toJS(vm
如何为包含多态对象集合的复杂模型编写自定义模型绑定(bind)程序? 我有下一个模型结构: public class CustomAttributeValueViewModel { publi
您好,我正在尝试实现我在 this article 中找到的扩展方法对于简单的注入(inject)器,因为它不支持开箱即用的特定构造函数的注册。 根据这篇文章,我需要用一个假的委托(delegate)
你好,我想自动注册我的依赖项。 我现在拥有的是: public interface IRepository where T : class public interface IFolderReposi
我正在使用 Jasmine 测试一些 Angular.js 代码。为此,我需要一个 Angular 注入(inject)器: var injector = angular.injector(['ng'
我正在使用 Matlab 代码生成器。不可能包含代码风格指南。这就是为什么我正在寻找一个工具来“ reshape ”、重命名和重新格式化生成的代码,根据我的: 功能横幅约定 文件横幅约定 命名约定 等
这个问题在这里已经有了答案: Where and why do I have to put the "template" and "typename" keywords? (8 个答案) 关闭 8
我开发了一种工具,可以更改某些程序的外观。为此,我需要在某些进程中注入(inject)一个 dll。 现在我基本上使用这个 approach .问题通常是人们无法注入(inject) dll,因为他们
我想使用 swing、spring 和 hibernate 编写一个 java 应用程序。 我想使用数据绑定(bind)器用 bean 的值填充 gui,并且我还希望它反射(reflect) gui
我有这段代码,当两个蜘蛛完成后,程序仍在运行。 #!C:\Python27\python.exe from twisted.internet import reactor from scrapy.cr
要点是 Spring Batch (v2) 测试框架具有带有 @Autowired 注释的 JobLauncherTestUtils.setJob。我们的测试套件有多个 Job 类提供者。因为这个类不
我是一名优秀的程序员,十分优秀!