我将尝试解释这一点而不显示任何代码,因为我认为我不需要......
我创建的对象包含数据和几种从Web服务器访问数据的方法,在这种情况下,它会填充所述数据以供日后检索。
在主线程中,当视图初始化时,我使用访问数据所需的URL初始化此对象。这就是它初始化时所做的一切......然后,一旦视图加载,我调用一个对象的方法,然后从Web服务器获取数据。这可能需要几秒或更长时间才能深入了解正在检索的数据。之后,我可以调用其他方法来获取我需要的不同类型的数据。
我的问题是我似乎无法找到将其放入另一个线程的最佳方法。执行一个简单的performSelectorInBackground似乎不起作用,因为无法访问初始化视图时初始化的对象。第二个线程无法找到它的原因。理论上,我可以初始化对象并运行我需要在第二个线程内运行的方法。然后将对象传递回主线程......我正在查看可能正在执行performSelectorOnMainThread并以此方式传回对象。那会有用吗?
理想情况下,有一些东西可以让我:
不幸的是,它看起来并不那么容易。任何有助于我指向正确方向的帮助将不胜感激。或者至少证实我关于将物体传回的理论就足够了。
编辑:我如何读取和修改我在我的视图控制器的头文件中定义的实例变量?当我在第二个线程中运行的方法中设置断点时,就像变量尚未初始化一样。
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就好了。我不明白这里发生了什么。我唯一的猜测是垃圾收集器不喜欢我,但那只是猜测。再一次,任何帮助都会很棒。
答案 0 :(得分:0)
1)iOS中没有垃圾收集。内存管理行为将始终保持一致,直至您自己的代码的非确定性行为(例如竞争条件)。
如果相同的代码在一个新项目中有效,那么它或者它不是完全相同的代码,或者它是偶然的(访问一个解除分配的对象可以偶尔工作,它只是一个等待发生的崩溃虽然),或者你的代码中有一些非确定性条件释放对象。
2)要做到这一点:
在另一个线程中运行一些代码......
等待所述代码完成...
继续执行该计划的其余部分。
您可以使用以下其中一项:
performSelector ...方法系列,就像你使用它们一样。
dispatch_async函数系列 - 查找它,你会发现很多 实例
将NSInvocationOperation / NSBlockOperation与完成块一起使用 它将控制权转回主线程。
特别是对于HTTP请求,您可以使用ASIHTTPRequest(也在内部使用NSOperation,但为请求的进度提供了许多额外的功能和回调)。