iOS线程,第二个线程看不到变量?

时间:2011-10-15 00:43:49

标签: ios multithreading

我将尝试解释这一点而不显示任何代码,因为我认为我不需要......

我创建的对象包含数据和几种从Web服务器访问数据的方法,在这种情况下,它会填充所述数据以供日后检索。

在主线程中,当视图初始化时,我使用访问数据所需的URL初始化此对象。这就是它初始化时所做的一切......然后,一旦视图加载,我调用一个对象的方法,然后从Web服务器获取数据。这可能需要几秒或更长时间才能深入了解正在检索的数据。之后,我可以调用其他方法来获取我需要的不同类型的数据。

我的问题是我似乎无法找到将其放入另一个线程的最佳方法。执行一个简单的performSelectorInBackground似乎不起作用,因为无法访问初始化视图时初始化的对象。第二个线程无法找到它的原因。理论上,我可以初始化对象并运行我需要在第二个线程内运行的方法。然后将对象传递回主线程......我正在查看可能正在执行performSelectorOnMainThread并以此方式传回对象。那会有用吗?

理想情况下,有一些东西可以让我:

  1. 在另一个线程中运行一些代码......
  2. 等待所说的代码完成......
  3. 继续执行该计划的其余部分。
  4. 不幸的是,它看起来并不那么容易。任何有助于我指向正确方向的帮助将不胜感激。或者至少证实我关于将物体传回的理论就足够了。

    编辑:我如何读取和修改我在我的视图控制器的头文件中定义的实例变量?当我在第二个线程中运行的方法中设置断点时,就像变量尚未初始化一样。

    EDITx2:

    - (id)initWithText:(NSString *)strURL{
        if (self) {
            // Custom initialization
            osSearch = [[orgSearch alloc] initWithurl:strURL];
        }
        return self;
    }
    - (void)viewDidLoad{
        [self loadSearches];
        [super viewDidLoad];  
    }
    - (void)loadSearches{      
        [self performSelectorInBackground:@selector(workerThread) withObject:nil];
    }
    -(void) workerThread{
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        [osSearch go];
        [self performSelectorOnMainThread:@selector(returnToMain) withObject:nil waitUntilDone:FALSE];
        [pool release]; 
    }
    -(void)returnToMain{
            UITableView* tblView = tableView;
            tblView.frame = CGRectMake(0,28,320,387);
            [tblView release];
    }
    

    osSearch是我试图访问的对象,但好像我的所有ivars都被释放了。如果我在performSelectorInBackground上休息,我可以看到osSearch已正确初始化。一旦我进入了workerThread,就像它从未如此。我可以注释掉“go”的调用,然后返回主线程,看起来它仍然没有被初始化。

    就像测试一样,我创建了一个新项目,使用相同的线程方法和对象,我能够创建新线程并访问视图的ivars和对象ivars就好了。我不明白这里发生了什么。我唯一的猜测是垃圾收集器不喜欢我,但那只是猜测。再一次,任何帮助都会很棒。

1 个答案:

答案 0 :(得分:0)

1)iOS中没有垃圾收集。内存管理行为将始终保持一致,直至您自己的代码的非确定性行为(例如竞争条件)。

如果相同的代码在一个新项目中有效,那么它或者它不是完全相同的代码,或者它是偶然的(访问一个解除分配的对象可以偶尔工作,它只是一个等待发生的崩溃虽然),或者你的代码中有一些非确定性条件释放对象。

2)要做到这一点:

  

在另一个线程中运行一些代码......

     

等待所述代码完成...

     

继续执行该计划的其余部分。

您可以使用以下其中一项:

  1. performSelector ...方法系列,就像你使用它们一样。

  2. dispatch_async函数系列 - 查找它,你会发现很多 实例

  3. 将NSInvocationOperation / NSBlockOperation与完成块一起使用 它将控制权转回主线程。

  4. 特别是对于HTTP请求,您可以使用ASIHTTPRequest(也在内部使用NSOperation,但为请求的进度提供了许多额外的功能和回调)。