当用户在我的iPad应用中切换页面时,我正在使用以下代码显示页码。该数字应该显示在一个漂亮的透明灰色窗格中(类似于XCode中的“Build Succeeded”消息)。但是,图像视图仅显示约5%的时间。 (我还没有添加代码来在窗格中放置一个数字)。每次都会显示NSLog()
消息。我还设置了断点并逐步完成,UIImageView
代码被调用。可悲的是,我无法进入框架看看它在做什么。
使用的变量都是本地或常量,所以我怀疑它与竞争条件有关。此外,我可以在点击之间等待几分钟而不是获取图像,或者快速按下按钮并获得多个堆叠图像(它们是透明的,因此很容易注意到堆叠)。
我尝试在setNeedsDisplay
之后在self.view
上运行addSubview:
(即使我非常确定addSubview:
这样做),但这没有做任何事情。
直接调用displayPageNumber:
,无需线程,也不会使其始终显示。
有什么想法吗?
#define PageDisplayTime 0.5
#define PageDisplayImageName @"PageIndicator.png"
#define PageDisplayImage [UIImage imageNamed: PageDisplayImageName]
...
[NSThread detachNewThreadSelector: @selector(displayPageNumber:)
toTarget: self withObject: index];
...
- (void) displayPageNumber: (NSNumber*) _pageIndex
{
NSLog(@"Page Number: '%d'.", [_pageIndex integerValue] + 1);
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
UIImageView* glassPaneView = [[UIImageView alloc] initWithImage: PageDisplayImage];
glassPaneView.center = CGPointMake(300.0, 300.0);
[self.view addSubview: glassPaneView];
[NSThread sleepForTimeInterval: PageDisplayTime];
[glassPaneView removeFromSuperview];
[glassPaneView release];
[pool release];
}
答案 0 :(得分:1)
AFAIK所有UI编码必须在主线程上完成。在后台线程上执行此操作最多会产生不可预测的结果,更糟糕的是会崩溃。
直接调用方法(因此在主线程中)不起作用,因为sleep只是停止当前线程,因此在删除视图之前它无法执行任何操作,包括绘制,从而阻止它显示。 / p>
您必须将方法重构为主线程上调用的多个方法。第一个只是添加子视图并设置一个计时器,计时器处理方法然后删除子视图。
答案 1 :(得分:0)
我想出了这个问题。如果其他人碰到这个,这里是:
addSubview:
/ removeFromSuperview
对与它们之间的sleepForTimeInterval:
基本没用。我知道睡眠阻止了线程,但显然此线程需要被解除阻塞才能更新视图。我假设(错误地看来)视图更新发生在主线程上。
这是我的替代解决方案:
取消隐藏主线程中的子视图,并使用睡眠X秒的消息调用detachNewThreadSelector:
,然后隐藏子视图。
我将添加一个NSLock
ed计数器,该计数器在取消隐藏时递增,并在hider消息中递减,但仅在计数器降至0时隐藏。这将允许重复激活以延长持续时间。 / p>