2009-06-28 12 views
0

Webサービスへのログインを実行し、ログイン中に受信したsessionidを使用してオブジェクトのリストを要求するアプリケーションがあります。NSOperation内から他のオブジェクトにアクセスする方法は?スレッドの問題がクラッシュする

Appdelegate.h

.... 
@property (nonatomic, retain) NSString *sessionId; 

AppDelegate.m:

-(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]; 

} 

LoginOperation:

-(void) main { 
... 
[[UIApplication sharedApplication] delegate] setSessionId:sessionID]; 
... 

} 

ListOperation:

-(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 detach ...の代わりにNSOperationを使用します。

このような状況に最適なパターンは何ですか?並行操作としてListOperationを定義していますか?私はコンカレントオペレーションを定義することで複雑な混乱を望んでいません。

私のケースはかなり単純だと思いますが、単純な解決策が必要ですか?

+0

競合状態またはオーバーリリースオブジェクトのように聞こえる。 sessionIDを作成していますか?クラッシュは何ですか?バックトレース? ここにはデバッグするための十分な情報がありません。 – bbum

+0

デバッガは、私がアクセスしているオブジェクトが有効だが、オブジェクトのすべてのプロパティが無効であることを示しています。 NSOperation内からシングルトンオブジェクトにアクセスしようとしましたが、同じクラッシュ条件が発生します。 したがって、BAD_ACCESSがクラッシュします。 – Rod

+0

私はこのメソッドをstart()メソッドとすべてを使ってConcurrent NSOperationにしようとしました。 マニュアルでは、新しいスレッドでconcurrentが実行されると記載されています。だから私はそれが問題を解決するかもしれないと思った。 しかし、そうではありません。クラッシュはまったく同じです! – Rod

答えて

0

ゾンビ(NSZombieEnabled環境変数)をオンにして、オーバーフリーであるかどうかを確認します。

[[[UIApplication sharedApplication] delegate] sessionId]を記録してstringWithStringの前にあるかどうかを確認します(nilの場合は例外が発生します)。

と言えば、[NSString stringWithString:xxx]はまったく役に立ちません。それを遂行しようとしているものは何でも、それは助けにならないでしょう - memory management rulesを読んでください。

各メインの開始/終了にNSLogを追加して、期待通りに同期していることを確認します。

「それはクラッシュします」という質問は、あまりにもあまりにも曖昧です。クラッシュバックトラックの詳細を含めてください。

+0

ログ[[[UIApplication sharedApplication] delegate] sessionId]の結果、BAD ACCESSがクラッシュします。 しかし、Appdelegateは有効なオブジェクトです! これは非常に奇妙な問題です。 – Rod

+0

@Roman - つまり、あなたのsessionIDプロパティがオーバーリリースされています。 bbumが尋ねると、実際のsessionIDを作成する場所にコードを投稿します。 –

+0

NSZombieEnabledを有効にする(実行可能ファイルの設定では、引数パネルで環境変数NSZombieEnabled = YESを追加します)また、質問を編集してsessionIDを参照するすべてのコードを表示してください。 –

0

ある操作を別の操作の依存関係として追加できます。従属操作が完了するまで、もう一方は実行されないことが保証されます。また、コード内でsessionIDを使用する場所であれば、ログイン操作がすでに完了していることを確認する必要があります。あなたのコードに基づいて、依存関係を追加する例:

- (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]; 
} 

さて、listOperationは間違いloginOperationが完了するまで実行されません。

+0

ヒントをありがとう。 しかし、NSOperationの内部からsessionIDにアクセスすることは私の問題を解決しません。 – Rod

関連する問題