【发布时间】:2012-01-24 22:10:51
【问题描述】:
关于这个警告的另一个呼救声。
首先,我已经查看了其他地方的所有问题,但似乎没有一个适合我的情况。它与警报框和辞去第一响应者无关,也与在显示视图之前执行任何动画无关。实例化基于 UIView 的自定义键盘时出现我的问题。
其次,我相信我可以让警告随意出现/消失。我只是很困惑为什么,所以我更多的是寻找解释而不是解决方案。
这里的代码太多了,所以我只概述一下发生了什么:
ViewController "Calc" 在 VC 的 loadView 方法中实例化一个基于 UIView 的自定义 "DataView",然后将其添加为 VC 的子视图。
“DataView”在 DataView 的 init 方法中实例化一个基于自定义 UITextField 的“TextFieldKPD”
“TextField”在 TextField 的 init 方法中实例化一个基于 UIView 的自定义“KeyPad”,并将该 KeyPad 分配给 TextField 的 inputView。
“键盘”创建 13 个 UIButtonTypeCustom 类型的 UIButton,读取并为每个按钮分配“按下”和“未按下”图像,以及设置按钮的操作。然后它将每个按钮添加为其自身的子视图。 (通过控制这种构造发生在 KeyPad 的 UIView 生命周期中的时间,我可以影响 wait_fences 警告:见下文。)
“Calc”视图控制器是最初呈现给用户的视图控制器。我已经追踪到在 Calc 的 viewDidLayoutSubViews 方法结束之后和调用其 viewDidAppear 方法之前发生的 wait_fences 警告。请注意,显示 Calc 时,KeyPad 是不可见的。
我似乎能够通过更改键盘的构造方式来控制 wait_fences 警告的操作:
如果 UIButtons 被实例化并作为子视图添加到 KeyPad 的 init 方法中,那么我只会收到一次警告。
如果在 KeyPad 的 layoutSubViews 方法中实例化并添加按钮,则不会出现警告。 (但是在我点击 TextField 之前,KeyPad 并没有有效地构建 - 仍然没有 wait_fences 警告)
Calc 的 loadView 中没有动画或任何内容。一直实例化并赋值。
那么这个版本的wait_fences 上有没有cmets?
编辑 1,1 月 30 日 - 现在更加混乱!
今天早上我很无聊,所以我决定玩一下我的代码,看看我是否可以更好地隔离警告的生成。我将其范围缩小到以下完全无用的代码,现在我可以使用这些代码触发警告:
-(void)loadImages
{
UIImage* image;
for(int i=0; i<16; i++) {
image = [UIImage imageNamed:@"StupidFileNameThatDoesNotExist"];
}
}
如果我在KeyPad 的init 方法中执行[self loadImages],则会出现警告。但是这个代码什么都不做,因为文件不存在。我相信如果循环计数器足够小以至于警告确实消失了,但我没有限定下限。
如果我用
替换图像的实际加载[UIImage imageWithContentsOfFile:@"StupidFileNameThatDoesNotExist"]
并且在KeyPad init 期间仍然调用该方法,那么我似乎没有收到警告。这两种加载图像的方式之间的一个明显区别是imageNamed 在内部缓存图像。
所以我倾向于 George 的回答,即这是 Apple 内部搞砸了。
编辑 2,2 月 1 日 - 这是吉姆的警告,但不是我们所知道的
所以我说服自己,显然是 UIImage 类中的缓存导致了这个问题。该怎么办?好吧当然是写我自己的图片缓存!!
所以我开始停止工作,删除那些试图加载无效图像的代码,并得到我生成所需文件名并将它们传递给我的缓存控制器的点。因此,为了验证事情是否开始融合在一起,在缓存控制器中,我为每次缓存图像的尝试生成了一条 NSLog 消息 - 仅此而已 - 只需记录文件名。
你猜怎么着——我又收到了愚蠢的警告。因为根本没有做任何实际工作。
我只能得出结论,当我将额外代码塞入KeyPad 的 init 方法时,我触发了某种内部 iOS 竞争条件。而且我无能为力来减轻它。我所能做的就是希望这个警告是良性的。
编辑 3,《哈姆雷特》第 1 场第 4 场:丹麦州有些东西烂了
保持与编辑 2 中相同的代码,我注释掉了 NSLog 语句。警告消失了。我把它放回去,警告出现了。
所以我的代码是:
-(void)loadImages
{
// Iterate over button definitions and cache the required images
for(int i=0; i<numKeys; i++) {
if (![imageCache imageExistsForTag:keyTags[i]]) {
[imageCache addImageFile:[NSString stringWithFormat:@"%s_NP.png",keyNames[i]] forTag:keyTags[i]];
}
if (![imageCache imageExistsForTag:keyTags[i]+pressedOffset]) {
[imageCache addImageFile:[NSString stringWithFormat:@"%s_P.png",keyNames[i]] forTag:keyTags[i]+pressedOffset];
}
}
}
还有:
-(void)addImageFile:(NSString*)imageFile forTag:(int)tag
{
NSLog(@"Adding tag:%d for file %@", tag, imageFile);
}
使用 NSLog 语句控制警告的外观。
编辑 4,2 月 2 日 - 欢迎来到末日神殿
考虑到 Allen 的 cmets,我将我的键盘重新构建为 XIB 并加载它,而不是手动尝试构建视图。当然,这并没有解决任何问题。我曾希望 Nib 加载会发生在导致问题的原因之外。
我的直觉是,我正在与 Calc 的 loadView 和一些内部 iOS 活动中的竞争条件发生冲突。如果我在 loadView 中做太多工作,那么我会越界并触发 wait_fences 警告。而且键盘是一种症状,而不是根本原因。 IE 它可能是任何活动,只是键盘工作是我在警告开始出现之前所做的最后一件事。我只是希望我真的知道我实际上正在跨越的限制是什么,而不是在黑暗中跌跌撞撞。
【问题讨论】:
-
彼得,你的 26 个按钮图像有多大?这些图像的加载似乎超出了苹果要求的 10 秒限制,您是否考虑过将所有 UI 放在一个 nib 中?
-
@Allen .. 目前我什至没有加载图像。我所做的只是创建图像的名称并将该信息发送到 NSLog。而且我刚刚运行了一个测试..从我点击 XCode 中的 Run 按钮到出现警告的时间为 5 秒。从我的第 4 代 iPod touch 运行时,应用程序在不到 2 秒的时间内启动。
-
用这些图片来计算整个加载时间,然后重新考虑将所有这些固定的 UI 放到一个 nib 中。
-
@Allen .. 这个问题与实际图像本身无关(顺便说一句,它们都在 10kB 大小范围内)。我将在今天晚些时候重新审视图像的时间安排。但我的回忆是,该应用程序的启动时间相似。至于笔尖,现在我不确定笔尖中的自定义按钮是否提供与 UIImage 提供的“@2x”等相同的多分辨率图像加载。而且我的按钮不可拉伸。
-
@Allen - 刚刚计时。实际加载图像时,从 XCode->Run 到显示警告大约需要 6 秒。
标签: iphone objective-c ios5 wait-fences