UI 不会使用 PerformSelectoronMainThread 构建

发布于 2024-10-20 19:00:38 字数 1460 浏览 1 评论 0原文

我在下载和解析一些xml 时使用performSelectorInBackground。解析 xml 后,我会调用 PerformSelectorOnMainThread 来根据 xml 中的值构建 UI。构建 UI 函数确实被调用,但屏幕上没有显示任何内容。从后台线程调用主线程应该可以,不是吗?

如果我不在后台线程上执行 xml 解析,UI 添加就可以了。

-(id) myCustomInit:(Data *) data;

{
    if ( self= [super init]) {
            baseURL=data.url;
    [self performSelectorInBackground:@selector(getXML) withObject:nil];

    }


    return self;

}


-(void) getXML
{
    // Set up a pool for the background task.

    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

    // XML parsing code removed for brevity



    [self performSelectorOnMainThread:@selector(handleUIOnXMLComplete) withObject:nil waitUntilDone:YES];

    [pool release];


}

-(void)handleUIOnXMLComplete
{

// add buttons etc to view

    UIButton *button=[UIButton buttonWithType:UIButtonTypeRoundedRect];

[self.view addSubview:button];

}

编辑

这是父 UIViewController 中的代码,这实际上添加了视图

- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
    NewViewData *rld=nil;

    rld=[dataArray objectAtIndex:indexPath.row];
    NewView *controller = [[NewView alloc] myCustomInit:rld ];


    controller.title = rld.Title;
    controller.view.backgroundColor = [UIColor blackColor];

    [table.navigationController pushViewController:controller animated:YES];
    //[table.tableView reloadData];

}

I'm using performSelectorInBackground in download and parse some xml. Once the xml is parsed I call performSelectorOnMainThread to build my UI based on values in the xml. The build UI function does get called but nothing gets put onto the screen. It should be o.k to call the main thread from a background thread should it not?

If I don't perform the xml parsing on a background thread the UI add just fine.

-(id) myCustomInit:(Data *) data;

{
    if ( self= [super init]) {
            baseURL=data.url;
    [self performSelectorInBackground:@selector(getXML) withObject:nil];

    }


    return self;

}


-(void) getXML
{
    // Set up a pool for the background task.

    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

    // XML parsing code removed for brevity



    [self performSelectorOnMainThread:@selector(handleUIOnXMLComplete) withObject:nil waitUntilDone:YES];

    [pool release];


}

-(void)handleUIOnXMLComplete
{

// add buttons etc to view

    UIButton *button=[UIButton buttonWithType:UIButtonTypeRoundedRect];

[self.view addSubview:button];

}

Edit

This is the code in the parent UIViewController Thats actually adds the view

- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
    NewViewData *rld=nil;

    rld=[dataArray objectAtIndex:indexPath.row];
    NewView *controller = [[NewView alloc] myCustomInit:rld ];


    controller.title = rld.Title;
    controller.view.backgroundColor = [UIColor blackColor];

    [table.navigationController pushViewController:controller animated:YES];
    //[table.tableView reloadData];

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

锦爱 2024-10-27 19:00:38

从后台线程触发对主线程上的方法的调用是允许的并且没问题。

setNeedsLayout 和 setNeedsDisplay 不需要调用——当您向视图添加子视图时,无论如何都会触发新添加项目的显示。

如果将整个handleUIOnXMLComplete 方法替换为以下内容,会发生什么情况?

-(void)handleUIOnXMLComplete
{

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
    label.text = @"XXXXXXX YYYYYYYY";
    label.backgroundColor = [UIColor yellowColor];
    [self.view addSubview:label];
}

我尽可能地快速复制了您的情况,上面的代码确实有效——我看到了“XXXXXXX YYYYYYYY”标签。

顺便说一下,我会避免设置一个全新的 self.view —— 最好修改现有的 self.view。

顺便说一句,在您发布的代码中,您没有在自定义 UIButton 上设置框架!因此,在制作按钮之后并将其添加到视图之前,请执行类似 button.frame = CGRectMake(0.0, 0.0, 160.0, 160.0); 的操作。

Triggering a call to a method on the main thread, from a background thread, is allowed and fine.

setNeedsLayout and setNeedsDisplay shouldn't need calling -- when you add a subView to a view, the display of the newly added item is triggered anyway.

What happens if you replace your entire handleUIOnXMLComplete method with the following?

-(void)handleUIOnXMLComplete
{

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
    label.text = @"XXXXXXX YYYYYYYY";
    label.backgroundColor = [UIColor yellowColor];
    [self.view addSubview:label];
}

I did a quick reproduction, as far as I could, of your situation and the above code does work -- I get to see the "XXXXXXX YYYYYYYY" label.

I'd avoid setting a whole new self.view by the way -- it's preferable to modify the existing self.view.

By the way, in the code you posted, you're not setting a frame on your custom UIButton! So do something like button.frame = CGRectMake(0.0, 0.0, 160.0, 160.0); after you make your button and before you add it to the view.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文