强制UIScrollView更新

时间:2011-02-17 17:21:33

标签: objective-c multithreading uiscrollview


我遇到了这个问题我有一系列 CharacterView 类的页面直接进入UIScrollView。
装载部分是非常性能密集的,因为这个原因我试图借助线程方案来管理它 我的目的是加载请求的页面(例如,第10页中的第5页)并开始从那里加载此UIScrollView的所有页面并立即在屏幕上显示,然后以某种方式重复并加载+1 / -1(分别) 6和4)和show'em在屏幕上,然后在第二次递归加载+2 / -2(第7和第3)和show'em在屏幕上等等..

这是代码:

-(void)loadPagesDrillingFromPage:(NSInteger) page {
    self.viewControllers = [[[NSMutableArray alloc] init] autorelease];
    for (unsigned i = 0; i < [pageIds count]; i++) {
        [self.viewControllers addObject:[NSNull null]];
    }
    pageControl.numberOfPages = [pageIds count];
    didPreparePagesContainer = YES;

    if (kPRELOADALLPAGES && !threadIsLoadingPages) {
        threadIsLoadingPages = YES;
        NSNumber *startingPage = [NSNumber numberWithInt:page];
        NSMutableArray *preloadedPages = [[[NSMutableArray alloc] init] autorelease];
        [NSThread detachNewThreadSelector:@selector(drillPagesFrom:) toTarget:self withObject:startingPage];  
    }
}

正如你在这个函数中看到的那样,我们从开始使用选择器drillPagesFrom :( NSNumber *)页面调用该线程,该页面定义为广告如下:

-(void)drillPagesFrom:(NSNumber *) page {
    NSInteger pg = [page intValue];
    CharacterView   *controller = [self.viewControllers objectAtIndex:pg];
    if((NSNull *)controller != [NSNull null])
        return;

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSLog(@"DRILLING page %i", pg); 

    controller = [[CharacterView alloc]
                                 initWithNibName:@"CharacterView"
                                 bundle:[NSBundle mainBundle]];
    controller.didLoad = NO;
    controller.position = pg;
    controller.containerItemsCount = [self.pageIds count];
    controller.delegate = self;
    CGRect frame = self.scrollView.frame;
    frame.origin.x = frame.size.width * pg;
    frame.origin.y = 0;
    controller.view.frame = frame;
    [controller setCat_name:self.cat_name];
    [controller fetchCharacter:[self.pageIds objectAtIndex:pg] WithMOC:self._context];
    [self.viewControllers replaceObjectAtIndex:pg withObject:controller];
    [self performSelectorOnMainThread:@selector(updateScrollView:) withObject:controller waitUntilDone:NO];
    [controller release];

    if(pg > 1)// && !threadReachedFirstPage)
    {
        NSNumber *prevPg = [NSNumber numberWithInt:pg-1];
        [self drillPagesFrom:prevPg];
    }
    if(pg < [self.pageIds count]-1)// && !threadReachedLastPage)
    {
        NSNumber *nextPg = [NSNumber numberWithInt:pg+1];
        [self drillPagesFrom:nextPg];
    }

    [pool release];
}

经过各种测试后,我试图通过调用主线程强制重绘UIScrollView,正如您在上面的代码中所注意到的那样

    [self performSelectorOnMainThread:@selector(updateScrollView:) withObject:controller waitUntilDone:NO];

函数updateScrollView是

- (void) updateScrollView:(CharacterView *)controller {  
    [self.scrollView addSubview:[controller view]]; 
    [self.scrollView setNeedsDisplay];
}

尽管所有这些代码仍然在显示任何屏幕之前仍然等待加载所有页面,这非常非常烦人,因为你看到大约2秒的空白。

希望以明确的方式解释问题,
我提前感谢你。

欢呼声
k

2 个答案:

答案 0 :(得分:0)

您想要使用的是平铺滚动视图。这将让您只有一次需要在屏幕上显示的内容。查看Apple网站上的ScrollViewSuite示例代码。

答案 1 :(得分:0)

最后,我想出了setNeedsDisplay让我的一天。