0

私のView Controllerの1つで、別NSObjectのクラスから受け取った「GET」データに基づいてラベルを設定しています。明らかに、ラベルを設定するのにかかる時間は、データを取得するのにかかる時間よりはるかに短いため、ラベルは常に nil に設定されます。データのフェッチが完了するまでラベルが設定されないようにするにはどうすればよいですか。

NSObjectこれは、クラスで「取得」を実行するメソッドですmyClass

- (void) doGetURL:(NSString *) urlstring
callBackTarget:(id) target
callBackMethod:(NSString *) method
 failedMethod:(NSString *) method_failed
 {

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlstring]];
NSLog(@"-- get URL with cookie : [%@] and hash:(%@)", [self cookie], [self modhash]);
if (cookie && [cookie length] > 0)
{
    NSDictionary *properties = [NSDictionary dictionaryWithObjectsAndKeys:
                                cookieDomain, NSHTTPCookieDomain,
                                @"/", NSHTTPCookiePath, 
                                @"reddit_session", NSHTTPCookieName,
                                cookie, NSHTTPCookieValue,
                                //                                      [cookie stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], NSHTTPCookieValue,
                                nil];
    NSHTTPCookie *http_cookie = [NSHTTPCookie cookieWithProperties:properties];
    NSArray* cookies = [NSArray arrayWithObjects: http_cookie, nil];
    NSDictionary * headers = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
    [request setAllHTTPHeaderFields:headers];
}
NSURLConnection * connection = [NSURLConnection connectionWithRequest:request delegate:self];

NSString *connectionKey = [NSString stringWithFormat: @"%ld", ((intptr_t) connection)];
NSMutableDictionary *dl = [[NSMutableDictionary alloc] init];

[dl setValue:connectionKey forKey:@"connectionKey"];
if (target && method)
{
    [dl setValue:target forKey:@"afterCompleteTarget"];
    [dl setValue:method forKey:@"afterCompleteAction"];
}
[dl setValue:method_failed forKey:@"failedNotifyAction"];
[connections setValue:dl forKey:connectionKey];
}

それは別のメソッドで呼び出されていますmyClass

- (void)getUserInfo:(NSString*)user
{
NSString *getString = [NSString stringWithFormat:@"%@/user/%@/about.json",server,user];

[self doGetURL:getString callBackTarget:self callBackMethod:@"userInfoResponse:" failedMethod:@"connectionFailedDialog:"];
}

コールバック方法:

- (void)userInfoResponse:(id)sender
{    
NSLog(@"userInfoResponse in()");
NSData * data = (NSData *) sender;
NSError *error;

NSDictionary *json = [NSJSONSerialization
                      JSONObjectWithData:data

                      options:kNilOptions
                      error:&error];

NSDictionary *response = [json objectForKey:@"data"];

//futureLabelStr is a property of myClass
futureLabelStr = [response objectForKey:@"name"];;

}

次に、View Controller でラベルが設定されます。

- (void)viewDidLoad
{
[myClass getUserInfo:@"some_user"];

myLabel.txt = myClass.futureLabelStr;

}

もっと追加する必要があるか、できる限り整理しようとしましたが、何かを見落としている可能性があることをお知らせください。

4

2 に答える 2

3

情報が変更されたときに、viewController の viewDidLoad を「停止」したくない、通知したい。

myClass が完了して呼び出されたときに通知を送信するか-userInfoResponse:(NSNotificationCenter を参照)、myClass にデリゲート パターンを実装することで、これを行うことができます。viewController を myClass のデリゲートとして設定し、myClass がラベルを更新する viewController でフェッチを終了したときにデリゲート メソッドを呼び出すことができます。

または、コードを見て、 MVC パターンに違反しているため最善の方法ではありませんが、コードに最小限の変更を加えて、viewController をコールバック メソッドのレシーバーとして設定することもできます。

[self doGetURL:getString callBackTarget:viewController callBackMethod:@"userInfoResponse:" failedMethod:@"connectionFailedDialog:"];

もちろん、myClass の viewController への参照が必要であり、viewController はこのメソッドを実装する必要があります (これは MVC パターン違反です)。

于 2013-06-16T23:29:44.703 に答える
0

新しいスレッドでデータ呼び出しを送信し、通常どおり viewDidLoad を終了します。次に、これを取得している人(モデルである必要があります)からviewControllerにNSNotificationセンターを使用して、「ねえ、私はあなたのためにそのラベルを取得しました。取得して更新してください」と言います

次に、VC はモデルのデータを使用してラベルを設定します。NSNotificationCenter の使用については、このリンクを確認してください。

マルチスレッドについては、Grand Central Dispatch を参照してください。

于 2013-06-17T02:12:43.147 に答える