今日、私は次の質問をしました:ビューが押されたときに iOS ブロックが停止する
私が言及した操作 (OP1) は、実際には NSURLConnection を使用した、私のサーバーへの "http get" です。
さらに調査を重ねた結果、ブロックは実際には「死ぬ」わけではないことがわかりました。実際に何が起こるかというと、ビューがプッシュされた後でも ([NSThread sleep:10] で確認)、リクエストが実際に送信されます (サーバー側でログに記録されます)。サーバーは応答しますが、view2 がプッシュされた場合、アプリ側では何も起こりません! 接続がデリゲートを失ったかのように! 私が見ている別の可能性は、「NSURLConnectionがrsMainLoopに関連しているという事実ですか?」
誰でも助けることができますか?
Pls は次のことを忘れないでください:
0. 操作が完了するまで view2 がプッシュされない限り、すべて正常に動作します。
1. リクエストは非同期に送信されます
2. デリゲートを設定し、ビューが変更されない限り機能します
3. ビュー1は「シングルトン オブジェクト参照」プロパティ「OP1Completed」を使用して操作を開始します
4. ビュー2は OP1 の完了をチェックします「singleton オブジェクト参照」のプロパティ経由
5. ビュー2は、「singleton.OP1Result」プロパティに移動して「結果」を取得します。
編集 1:
いくつかのコードを用意しましょう。最初に、シングルトンの関連コード (「Interaction」という名前) を次に示します。
-(void)loadAllContextsForUser:(NSString *)username{
userNameAux = username;
_loadingContextsCompleted = NO;
if (contextsLoaderQueue == NULL) {
contextsLoaderQueue = dispatch_queue_create("contextsLoaderQueue", NULL);
}
dispatch_async(contextsLoaderQueue, ^{
NSLog(@"Loading all contexts block started");
[self requestConnectivity];
dispatch_async(dispatch_get_main_queue(), ^{
[Util Get:[NSString stringWithFormat:@"%@/userContext?username=%@", Util.azureBaseUrl, [username stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]
successBlock:^(NSData *data, id jsonData){
NSLog(@"Loading all contexts block succeeded");
if([userNameAux isEqualToString:username]){
_allContextsForCurrentUser = [[NSSet alloc]initWithArray: jsonData];
}
} errorBlock:^(NSError *error){
NSLog(@"%@",error);
} completeBlock:^{
NSLog(@"load all contexts for user async block completed.");
_loadingContextsCompleted = YES;
[self releaseConnectivity];
}];
});
while (!_loadingContextsCompleted) {
NSLog(@"loading all contexts block waiting.");
[NSThread sleepForTimeInterval:.5];
}
});
NSLog(@"Load All Contexts Dispatched. It should start at any moment if it not already.");
}
そして、これが実際に要求/応答を処理する Util クラスです。
-(id)initGet:(NSString *)resourceURL successBlock:(successBlock_t)successBlock errorBlock:(errorBlock_t)errorBlock completeBlock:(completeBlock_t)completeBlock;{
if(self=[super init]){
_data=[[NSMutableData alloc]init];
}
_successBlock = [successBlock copy];
_completeBlock = [completeBlock copy];
_errorBlock = [errorBlock copy];
NSURL *url = [NSURL URLWithString:resourceURL];
NSMutableURLRequest *request = [NSURLRequest requestWithURL:url];
[[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
//[_conn scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
//[_conn start];
NSLog(@"Request Started.");
return self;
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[_data setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[_data appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
id jsonObjects = [NSJSONSerialization JSONObjectWithData:_data options:NSJSONReadingMutableContainers error:nil];
id key = [[jsonObjects allKeys] objectAtIndex:0];
id jsonResult = [jsonObjects objectForKey:key];
_successBlock(_data, jsonResult);
_completeBlock();
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
_errorBlock(error);
_completeBlock();
}
最後に、関連する部分 VC1 を示します (VC2 を押し込みます)。
- (IBAction)loginClicked {
NSLog(@"login clicked. Preparing to exibit next view");
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil];
AuthenticationViewController *viewController = (AuthenticationViewController *)[storyboard instantiateViewControllerWithIdentifier:@"ContextSelectionView"];
NSLog(@"Preparation completed. pushing view now");
[self presentViewController:viewController animated:YES completion:nil];
}