相关疑难解决方法(0)

如何,简单地等待iOS中的任何布局?

在开始注意之前,这与后台处理无关.没有"计算"涉及到背景.

只有UIKit.

view.addItemsA()
view.addItemsB()
view.addItemsC()
Run Code Online (Sandbox Code Playgroud)

让我们说6s的iPhone

其中每一个都需要一秒时间才能构建UIKit.

这将发生:

一大步

他们一直都在出现.重复一遍,屏幕只会挂起3秒,而UIKit会做大量的工作.然后他们都出现了.

但是,让我说我希望这种情况发生:

在此输入图像描述

他们一直在进步.当UIKit构建一个屏幕时,屏幕会暂停1秒钟.它出现.它会在构建下一个时再次挂起.它出现.等等.

(注意"一秒钟"只是一个简单的例子.为了更全面的例子,请参阅本文末尾.)

你是如何在iOS中做到的?

您可以尝试以下方法.它似乎不起作用.

view.addItemsA()

view.setNeedsDisplay()
view.layoutIfNeeded()

view.addItemsB()
Run Code Online (Sandbox Code Playgroud)

你可以试试这个:

 view.addItemsA()
 view.setNeedsDisplay()
 view.layoutIfNeeded()_b()
 delay(0.1) { self._b() }
}

func _b() {
 view.addItemsB()
 view.setNeedsDisplay()
 view.layoutIfNeeded()
 delay(0.1) { self._c() }...
Run Code Online (Sandbox Code Playgroud)
  • 请注意,如果该值太小 - 这种方法很简单,显然也没有做任何事情.UIKit将继续努力.(它还会做什么?).如果价值太大,那就没有意义了.

  • 请注意,目前(iOS10),如果我没有弄错的话:如果你尝试使用零延迟的技巧,它最好不正常工作.(正如你可能期望的那样.)

跳转运行循环......

view.addItemsA()
view.setNeedsDisplay()
view.layoutIfNeeded()

RunLoop.current.run(mode: .defaultRunLoopMode, before: Date())

view.addItemsB()
view.setNeedsDisplay()
view.layoutIfNeeded()
Run Code Online (Sandbox Code Playgroud)

合理. 但是我们最近的实际测试显示,在许多情况下这似乎不起作用.

(也就是说,Apple的UIKit现在足够精致,可以将UIKit的工作涂抹在那个"技巧"之外.)

思考:在UIKit中,或许有一种方法可以获得一个回调,基本上,它已经绘制了你所堆积的所有视图了吗?还有其他解决方案吗?

一个解决方案似乎是......将子视图放在控制器中,因此您可以获得"didAppear"回调,并跟踪这些回调. 这似乎是婴儿,但也许这是唯一的模式?无论如何它真的会起作用吗?(仅仅是一个问题:我没有看到任何保证,确保确保所有子视图都已被绘制.)


如果这还不清楚......

日常用例示例:

•假设可能有七个部分.

•假设每个人通常需要0.01到0.20来构建UIKit(取决于您显示的信息).

•如果你只是"让一切都搞砸了"它通常会好或可以接受(总时间,比如0.05到0.15)......但......

•当"新屏幕出现"时,用户经常会有一个单调乏味的停顿.(.1到.5或更糟 …

performance runloop ios

29
推荐指数
2
解决办法
3780
查看次数

iOS游戏和运行循环管理

首先,我的问题是:你如何管理你的iOS Run-Loop?

接下来我的理由是:我一直在研究各种原型(v.早期开发),并发现了许多令人困惑的问题.

  • 首先,输入问题和运行循环让我尝试以下方法:
    • 当使用最推荐的系统(CADisplayLink)时,我注意到一旦CPU负载导致缓冲区翻转(presentRenderBuffer)必须等待一帧,某些触摸输入就会被丢弃.这只发生在设备而不是模拟器中(烦人的 - 这似乎与等待主线程上的vsync阻塞以及应用程序运行循环过程触摸输入和吃消息的方式有关)
    • 当使用下一个最推荐的系统(NSTimer)时,我注意到一旦CPU负载达到模拟器中的某个点而不是设备中的某个点(也令人讨厌),某些触摸输入就会被丢弃.NSTimer在我的更新发布时也会导致精度降低
    • 当使用推荐最少的系统(在内部使用由mach_absolute_time构建的高精度定时器管理自己的线程中运行运行循环时,我的所有触摸输入问题都会消失,但是我的ASSERT代码现在陷入了错误的线程,只有我睡着了跟随软件中断.(我的断言代码类似于http://iphone.m20.nl/wp/?p=1)我真的很喜欢我的断言代码陷阱导致问题,所以这个解决方案是对我来说不太适合:更难调试.
  • 第二,失去的时间:
    • 在调查系统时,我发现无论帧率如何(奇怪的是,但我认为统计上它仍然有意义w/vsync)我在vsync上等待大约22%的时间.我已经通过移动glFlush/glFinish并通过玩我多久经常进行presentRenderBuffer调用来证实这一点.这是我喜欢处理AI等关键时刻,而不是简单地停止阻塞gl调用.我能想到的唯一方法就是将渲染转移到它自己的线程中,但我不确定是否有理由开始在单处理器设备上重新构建多线程.

那么有没有人围绕这些问题找到了灵丹妙药?有没有人在这个平台上有一个杀手运行循环架构?目前看起来我必须选择较少的邪恶.

iphone optimization opengl-es runloop ios

28
推荐指数
1
解决办法
8515
查看次数

如何强制视图渲染自己?

在我的应用程序中,我有一些小的子视图.当用户点击子视图时,我会在点击的子视图(相同大小)的顶部放置一个单独的视图,然后将此单独视图设置为全屏大小.

放大视图是自定义绘制的,这对这种方法造成了很大的问题.如果我在主视图的viewDidLoad方法中创建放大视图并将其框架设置为全屏大小,drawRect则立即调用视图的方法,并且视图正确呈现为全尺寸.如果我然后在动画中使用此视图,一切都按预期工作.

但是,我需要这个放大视图根据所拍摄的子视图而有所不同,所以我需要每次重新创建/重新绘制它.问题是当我这样做以响应触摸事件时,视图的drawRect方法在动画开始之前不会被调用,此时视图的帧很小而不是全屏,因此一切都被绘制错误.

在我的触摸事件代码中,我明确地将视图的帧设置为全屏并setNeedsDisplay在开始动画之前调用,但这没有任何效果 - drawRect直到动画开始才调用.

有没有办法强制重绘,以便绘制视图,而其框架是我想要的大小?

iphone ios

14
推荐指数
1
解决办法
2万
查看次数

通过AVAssetReader读取样本

你如何通过AVAssetReader读取样本?我找到了使用AVAssetReader进行复制或混合的示例,但这些循环始终由AVAssetWriter循环控制.是否可以只创建一个AVAssetReader并通读它,获取每个样本?

谢谢.

iphone cocoa-touch objective-c avfoundation avassetreader

10
推荐指数
1
解决办法
2万
查看次数

运行循环/ drawRect中的神秘"渐进式减速"问题

这是一个真正的谜.

想象一下,您正在进行在屏幕外绘制复杂图像的传统过程(CGLayer),并且您在绘制时间歇性地将图像更新到屏幕上.

如您所知,执行此操作的方法是:在后台运行大型绘图过程,并根据需要调用setNeedsDisplays的前景,从而更新图像.这是微不足道的,可以通过两行代码实现.

但是,当你这样做时,会出现一个神秘的问题:每个绘图周期所花费的时间,每次都会增加,变得无法使用.此外,时间可能不规律地变化.

这是一个已知的iOS错误,还是?谁看过这个吗?

这是一个非常简单,非常容易理解的应用程序,可以解决问题:

http://www.fileswap.com/dl/p8lU3gAi/stepwiseDrawingV2.zip.html

输出示例如下.

有谁知道为什么会这样?操作系统的行为非常奇怪.

后来 ...... FELZ已经找到了令人震惊的解决方案.Felz副本的CGLayer一次每一轮.这完全阻止了这种奇怪的行为.

然而,对于究竟发生了什么仍然没有真正清楚的理解:因此从字面上看,当奇怪的问题出现时,时间在哪里?

这是一个很长的输出示例......

请注意,您有时会得到一个"双重奇异"的结果,如下所示:它表现出"正常"奇怪的行为:每次都会增加时间.然而,偶尔会有几轮时间"非常快",然后返回.怪啊?此外,如果您在模拟器上运行,请快速单击Mac上不相关的应用程序,以获得"更奇怪"的结果.

尽管费尔兹给出了一个完美的工作答案,但实际的机制仍然是一个谜.

:26:56.697 stepwiseDrawing[5334:1a03] time difference was     0
:26:56.707 stepwiseDrawing[5334:1a03] time difference was    10
:26:56.717 stepwiseDrawing[5334:1a03] time difference was    10
:26:56.744 stepwiseDrawing[5334:1a03] time difference was    27
:26:56.771 stepwiseDrawing[5334:1a03] time difference was    27
:26:56.807 stepwiseDrawing[5334:1a03] time difference was    37
:26:56.829 stepwiseDrawing[5334:1a03] time difference was    22
:26:56.864 stepwiseDrawing[5334:1a03] time difference was    35
:26:56.891 stepwiseDrawing[5334:1a03] time difference was    28
:26:56.936 stepwiseDrawing[5334:1a03] time difference was    45 …
Run Code Online (Sandbox Code Playgroud)

iphone cocoa drawrect ios

7
推荐指数
1
解决办法
1944
查看次数

setNeedsDisplay只被调用一次

在我的代码中,我希望"动画"绘制一条线的延迟,所以在向视图添加新行之后,我调用setNeedsDisplay - 它工作正常一次.

在drawRect方法中,我绘制线并调用线的方法来增加line-lengthl.现在我想再次调用setNeedsDisplay来重绘该行 - 所以它得到了一个"成长"的动画.

但它只调用setNeedsDisplay一次并且再也不会调用,除非我添加另一行.我也尝试在这个类中调用一个方法,它调用setNeedsDisplay,以确保你不能在drawRect中调用它.

- (void)drawRect:(CGRect)rect {

    for(GameLine *line in _lines) {

        if(line.done) {
            CGContextRef c = UIGraphicsGetCurrentContext();
            CGContextSetLineWidth(c, 5.0f);
            CGContextSetStrokeColor(c, lineColor);

            CGContextBeginPath(c);
            CGContextMoveToPoint(c, line.startPos.x, line.startPos.y);
            CGContextAddLineToPoint(c, line.endPos.x, line.endPos.y);
            CGContextStrokePath(c);
        }else {
            CGContextRef c = UIGraphicsGetCurrentContext();
            CGContextSetLineWidth(c, 5.0f);
            CGContextSetStrokeColor(c, delayColor);

            CGContextBeginPath(c);
            CGContextMoveToPoint(c, line.delayStartPos.x, line.delayStartPos.y);
            CGContextAddLineToPoint(c, line.delayEndPos.x, line.delayEndPos.y);
            CGContextStrokePath(c);

            [line incrementDelayLine];
            [self setNeedsDisplay];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

_lines是一个带有GameLine对象(非原子,保留)属性的NSMutableArray.

iphone objective-c drawrect method-call setneedsdisplay

2
推荐指数
1
解决办法
1265
查看次数

CGLayer绘图随着时间的流逝而变慢

谁能解释为什么重新绘制到屏幕外的CGLayer会导致渲染随时间推移而变慢?让我向您展示我为说明问题而创建的测试。

@implementation DrawView


- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        //setup frame rate monitoring
        fps = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 100, 20)];
        fps.textColor = [UIColor whiteColor];
        fps.font = [UIFont boldSystemFontOfSize:15];
        fps.text = @"0 fps";
        [self addSubview:fps];
        frames = 0;
        lastRecord = [NSDate timeIntervalSinceReferenceDate];

        //create a cglayer and draw the background graphic to it
        CGContextRef context = UIGraphicsGetCurrentContext();
        cacheLayer = CGLayerCreateWithContext(context, self.bounds.size, NULL);

        CGImageRef background = [[UIImage imageNamed:@"background.jpg"] CGImage];
        CGContextRef cacheContext = CGLayerGetContext(cacheLayer);
        CGContextDrawImage(cacheContext, CGRectMake(0, 0, 768, 1024), …
Run Code Online (Sandbox Code Playgroud)

core-graphics objective-c quartz-graphics ios

1
推荐指数
1
解决办法
3705
查看次数