使用线程时如何解决错误?

时间:2011-01-06 04:52:38

标签: iphone xcode ios ios4

使用NSThread时,我在控制台中有以下错误消息 “尝试从主线程或网络线程以外的线程获取Web锁定。这可能是从辅助线程调用UIKit的结果。现在崩溃......”

我已在此处提交示例代码

- (void)viewDidLoad {

    appDeleg = (NewAshley_MedisonAppDelegate *)[[UIApplication sharedApplication] delegate];
    [[self tblView1] setRowHeight:80.0];
    [super viewDidLoad];
    self.title = @"Under Ground";


    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    [NSThread detachNewThreadSelector:@selector(CallParser) toTarget:self withObject:nil];

}

-(void)CallParser {


    Parsing *parsing = [[Parsing alloc] init];
    [parsing DownloadAndParseUnderground];

    [parsing release];
    [self Update_View];
    //[myIndicator stopAnimating];
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;




}

这里“DownloadAndParseUnderground”是从rss提要下载数据的方法和

-(void) Update_View{


    [self.tblView1 reloadData];
}

调用Update_View方法时,tableView重新加载数据并在cellForRowAtIndexPath中创建错误而不显示自定义单元格

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {


    static NSString *CellIdentifier = @"Cell";

    CustomTableviewCell *cell = (CustomTableviewCell *) [tblView1 dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {

        [[NSBundle mainBundle] loadNibNamed:@"customCell"
                                      owner:self 
                                    options:nil];

        cell = objCustCell; 
        objCustCell = nil;

    }

5 个答案:

答案 0 :(得分:3)

  • 如果发生崩溃,则会有回溯。请发布。

  • 方法名称以小写字母开头,是camelCased,不包含下划线。遵循这些约定将使您的代码更容易被其他iOS程序员阅读,并且学习这些约定将使其更容易理解其他iOS程序员的代码。

您无法直接或间接从后台线程调用主线程中的方法。您的崩溃和代码都表明您可以自由地与非主线程的主线程进行交互。

documentation on the use of threads in iOS applications非常广泛。

答案 1 :(得分:2)

你的问题应该来了,因为你从一个不是主线程的线程加载你的UIViewController。当您在加载视图之前尝试对数据进行充电时。 要安排这个,您可以尝试这样做 1.添加一个只使用一个参数加载viewcontroller的方法

-(void)pushViewController:(UIViewController*)theViewController{
[self.navigationController pushViewController:theViewController animated:YES];}

2.在异步加载中将代码(下面评论)更改为“PerformSelectorOnMainThread”

    -(void)asyncLoadMyViewController
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    MyViewController *myVC = [[myVC alloc] initWithNibName:@"myVC" bundle:nil ];
   [self performSelectorOnMainThread:@selector(pushViewController:) withObject:myVC waitUntilDone:YES];
   //     [self.navigationController pushViewController:wnVC animated:YES];
    [wnVC release];
    [pool release];
}

答案 2 :(得分:0)

好请解释正确为什么在解析方法中需要线程?在你的代码中,你在正确的线程中使用表重载方法....

因为

你不能把任何与你的VIEW相关的东西放在线程中......

你只能把后台进程像解析一样...如果你想在解析之后重新加载表你可以在你的代码中使用一些标志值并在解析你的加载表之后

答案 3 :(得分:0)

尝试将CallParser方法更改为

-(void)CallParser {

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

    Parsing *parsing = [[Parsing alloc] init];
    [parsing DownloadAndParseUnderground];

    [self performSelectorOnMainThread:@selector(Update_View)
                           withObject:nil 
                        waitUntilDone:NO];
    [parsing release];
    [pool release];
}

移动

[UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 

行到Update_View方法

答案 4 :(得分:-1)

您无法从后台线程访问任何UI元素。您当然无法在后台线程上创建视图。使用“performSelectorOnMainThread”方法代替“detachNewThreadSelector”方法。

一切顺利。