【问题标题】:wait_fences: failed to receive reply: 10004003 (Again)wait_fences:未能收到回复:10004003(再次)
【发布时间】: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


【解决方案1】:

我之前遇到过几次这个问题,并试图找到解决方案。我得到的最接近的是,根据苹果工程师的说法,这是内部引起的问题,第三方开发人员不应该担心。据我所知,它不应该导致您的应用程序崩溃或导致任何问题,除了调试器中似乎让所有开发人员发疯的真正烦人的错误!

很抱歉,我无法提供更多帮助。

【讨论】:

  • 我会根据我完全无法理性地描述问题来回答这个问题。尽管从技术上讲这是一个无法回答的问题,但我的经验表明,这个问题不能由凡人来回答。现在谁是 iOS 的 Jon Skeet??
【解决方案2】:

据我所知,您的代码描述似乎是在子视图(例如 UIAlertView)在其父/超级视图之前创建时出现的。与响应者链有关。

尝试移动视图代码以解决问题或粘贴相关部分。

【讨论】:

  • 为了确保子视图是在他们的父母之后创建的,并且仍然存在同样的问题,我将所有的东西都移动了。我认为解决这个问题的很多方法是基于人们对修复导致其因他们的情况而消失的迷信,但实际上并没有解决根本问题。
【解决方案3】:

我从后台线程错误地运行 UIKit 代码时遇到了 wait_fences 错误。听起来这不是你的问题,但如果你还没有,那是另一回事。

【讨论】:

  • 我只有一个我正在使用的显式线程。不知道 iOS 在后台做什么。
【解决方案4】:

据我所知。 当我们调用 UIAlertView 并同时对 UIView 执行一些操作时,会出现此警告。 为了解决这个问题,我们当时不需要对 UIView 进行操作。 为此,我们可以做以下两件事中的任何一件: 1.我们可以延迟调用UIAlertView,以便完成对UIView的操作。 2.或者我们可以在方法中对UIView进行操作 - (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex; 这样在UIVIew上进行一些操作的时候,UIAlertView不在我们的UIView上。

希望对你有所帮助。

【讨论】:

  • 根据我的问题,我没有使用警报或执行任何动画。这只是关于在显示之前组装一个固定的视图层次结构。
【解决方案5】:

?我有点不清楚您的视图/视图控制器层次结构......

您有一个 ViewController“Calc”,它为它的“主”视图创建一个“DataView”。 “DataView”创建一个文本字段“TextFieldKPD”作为其自身的子视图。 "TextFieldKPD" 然后创建一个 UIView "KeyPad" 子视图,它自己为自己创建 13 个 UIButton 子视图。

所以你的观点有 4 个层次?

Apple 声明 ViewController 应该处理整个屏幕的视图(我想现在我们可以创建 containerViews,但其断言背后的意图仍然存在)。确保您的键盘按钮事件和文本字段事件由您的 viewController 处理。

您肯定会更好地在 viewController 或主视图中创建所有这些视图,以便您的层次结构更扁平?

如果我误解了你的层次结构,我深表歉意。

顺便说一句,要尝试的一件事是完全删除文本字段并查看是否仍然可以收到错误。

【讨论】:

  • Calc 有一个单独的视图,DataView 是 Calc 中的一个子视图。层次结构的其余部分是正确的。我有一个深层层次结构的原因是 DataView(以及其中的所有内容 - 它不仅包括文本字段)被多次实例化。在某些方面它类似于表格视图中的自定义单元格(但这里没有表格视图不合适)
  • 这听起来像是时间问题。尝试使用 NSTimer 来安排半秒后按钮的创建。
  • 我已经很确定这是一个时间问题。我想知道为什么是时间问题。
  • 这可能是一个疯狂的想法,但如果您不使用 for 循环来创建按钮,而是单独/手动创建它们会发生什么?
猜你喜欢
  • 2011-05-02
  • 2010-11-25
  • 1970-01-01
  • 1970-01-01
  • 2011-02-05
  • 2023-03-22
  • 2012-09-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多