How to access other objects from within NSOperation? Threading issues lead to crash
我有一个应用程序,该应用程序执行登录到Web服务的操作,然后使用在登录期间收到的sessionid来请求对象列表。
Appdelegate.h
1 2 | .... @property (nonatomic, retain) NSString *sessionId; |
AppDelegate.m:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | -(id)init{ queue = [[NSOperationQueue alloc] init]; [queue setMaxConcurrentOperationCount:1]; ..... } - (void)applicationDidFinishLaunching:(UIApplication *)application { LoginOperation *loginOperation = [[LoginOperation alloc] init]; [queue addOperation:loginOperation]; [loginOperation release]; ListOperation *listOperation = [[ListOperation alloc] init]; [queue addOperation:listOperation]; [listOperation release]; } |
登录操作:
1 2 3 4 5 6 | -(void) main { ... [[UIApplication sharedApplication] delegate] setSessionId:sessionID]; ... } |
ListOperation:
1 2 3 4 | -(void)main{ //Crashes at next line: NSString *sessionId = [[UIApplication sharedApplication] delegate] sessionId] ; } |
如果我在任何单例对象或AppDelegate中获得任何权限,则会崩溃。调试器显示单例对象或Appdelegate有效且已初始化,但该对象的ANY属性无效,并且访问导致崩溃。
这是一些奇怪的与线程相关的陷阱。我唯一能想到的是NSOperation在其线程中或类似的东西中具有所有其他对象的无效副本。
如果使用[NSThread detachNewThreadSelector:@selector(performList)toTarget:self withObject:nil]在手动生成的线程中执行相同操作,则不会崩溃;
我想使用NSOperation而不是NSThread分离...,因为NSOperation提供了队列。
这种情况的最佳模式是什么?将ListOperation定义为并发操作?我不希望在定义并发操作时遇到麻烦。
我认为我的案子很简单,应该有简单的解决方法吗?
尝试在Instruments中使用僵尸。真正有用的链接,之前帮助我跟踪了泄漏情况。不确定在线程化方案中这将如何有效。
http://www.markj.net/iphone-memory-debug-nszombie/
打开僵尸(NSZombieEnabled环境变量)以查看是否释放过多。
登录[[[[UIApplication sharedApplication]委托] sessionId],以验证stringWithString之前的内容(如果为nil,则将引发异常)。
说起来,[NSString stringWithString:xxx]绝对没有任何用处。无论您要完成什么,它都无济于事-重新读取内存管理规则。
在每个主节点的开头/末尾添加一个NSLog,以验证它们是否符合您的期望。
"崩溃"确实有点含糊不清,请提供崩溃回溯的更多详细信息。
您可以将一个操作添加为另一个操作的依赖项。这样就保证了另一个不会执行,直到相关操作完成为止。另外,在代码中使用sessionID的任何地方,都应确保"登录"操作已完成。根据您的代码添加依赖项的示例:
1 2 3 4 5 6 7 8 9 | - (void)applicationDidFinishLaunching:(UIApplication *)application { LoginOperation *loginOperation = [[LoginOperation alloc] init]; ListOperation *listOperation = [[ListOperation alloc] init]; [listOperation addDependency:loginOperation]; [queue addOperation:loginOperation]; [queue addOperation:listOperation]; [loginOperation release]; [listOperation release]; } |
现在,