Ios Objective-C:在完成方法的执行后,是否获得单例类方法的结果?

Ios Objective-C:在完成方法的执行后,是否获得单例类方法的结果?,ios,objective-c,objective-c-blocks,dispatch-async,Ios,Objective C,Objective C Blocks,Dispatch Async,我有一个检查应用程序登录状态的单例类 singleton类中有一个名为attemptologin的方法,该方法使用参数发出http请求,并返回有关登录状态的json数据。(对还是错) 现在,在主选项卡BarViewController中,我执行了以下操作: @interface CustomTabBarController () @end @implementation CustomTabBarController{ LoginCheckSingleton *loginSinglet

我有一个检查应用程序登录状态的单例类

singleton类中有一个名为
attemptologin
的方法,该方法使用参数发出http请求,并返回有关登录状态的json数据。(对还是错)

现在,在主
选项卡BarViewController
中,我执行了以下操作:

@interface CustomTabBarController ()

@end

@implementation CustomTabBarController{
    LoginCheckSingleton *loginSingleton;
    dispatch_queue_t myCustomQueue;
}
-(void)viewDidAppear:(BOOL)animated{
    myCustomQueue = dispatch_queue_create("com.myDomain.appName", NULL);
    loginSingleton = [LoginCheckSingleton sharedInstance];
    dispatch_sync(myCustomQueue, ^{
        [loginSingleton attemptToLogin];
    });
    if([loginSingleton.loginstat  isEqual: @"true"]){
        NSLog(@"Logged In");
    }else{
        NSLog(@"Not Logged In");
        [self performSegueWithIdentifier:@"goToLoginView" sender:self];
    }
}
这里的
dispatch\u sync
工作不正常,我想在dispatch\u sync中执行函数,并在执行其下的
if
语句之前获取结果。但是
if
语句是在dispatch\u sync内的块完成之前执行的

这是
单例类

#import "LoginCheckSingleton.h"
#import "AFNetworking.h"
#import "SSKeychain.h"
#import "CustomTabBarController.h"
static LoginCheckSingleton *sharedInstance = nil;
@interface LoginCheckSingleton (){
    NSString *serverURLString;
    NSURL *serverURL;
    NSString *userId;
    NSString *password;
    NSString *email;
    NSMutableArray *jsonContents;
    NSMutableDictionary *dictionary;
    NSString *loggedInStatus;
    bool loggedInTF;

}

@end
@implementation LoginCheckSingleton{
}


+ (LoginCheckSingleton*) sharedInstance {
    static dispatch_once_t _singletonPredicate;
    static LoginCheckSingleton *_singleton = nil;

    dispatch_once(&_singletonPredicate, ^{
        _singleton = [[super allocWithZone:nil] init];
    });

    return _singleton;
}

+ (id) allocWithZone:(NSZone *)zone {
    return [self sharedInstance];
}

-(void)attemptToLogin{
    // Retrieve credentials from Keychain
    userId = [SSKeychain passwordForService:@"com.lazemni.iFresh"
                                      account:@"ifreshUserId"];
    password = [SSKeychain passwordForService:@"com.lazemni.iFresh"
                                      account:@"ifreshPassword"];
    email = [SSKeychain passwordForService:@"com.lazemni.iFresh"
                                   account:@"ifreshEmail"];
    if(email == nil || password == nil){

        NSLog(@"empty username or password");
    }else{
        NSLog(@"not empty username or password");
        serverURLString = @"http://www.lazemni.com/demo/ifresh/api/login/";
        serverURLString = [serverURLString stringByAppendingString:email];
        serverURLString = [serverURLString stringByAppendingString:@"/"];
        serverURLString = [serverURLString stringByAppendingString:password];
        NSLog(@"%@",serverURLString);
        serverURL = [NSURL URLWithString:serverURLString];

        NSURLRequest *request = [NSURLRequest requestWithURL:serverURL];
        //AFNetworking asynchronous url request
        AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]
                                             initWithRequest:request];

        operation.responseSerializer = [AFJSONResponseSerializer serializer];
        [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
            jsonContents = [responseObject objectForKey:@"login"];
            NSLog(@"%@",jsonContents);
            dictionary = [jsonContents objectAtIndex:0];
            loggedInStatus = [dictionary objectForKey:@"status"];
            if([loggedInStatus  isEqual: @"true"]){
                NSLog(@"Succefully loggedin!");
                [SSKeychain setPassword:[dictionary objectForKey:@"user_id"] forService:@"com.lazemni.iFresh" account:@"ifreshUserId"];
                [SSKeychain setPassword:[dictionary objectForKey:@"email"] forService:@"com.lazemni.iFresh" account:@"ifreshEmail"];
                [SSKeychain setPassword:[dictionary objectForKey:@"password"] forService:@"com.lazemni.iFresh" account:@"ifreshPassword"];
                self.loginstat = @"true";
                loggedInTF = true;
            }else if([loggedInStatus  isEqual: @"false"]){
                NSLog(@"Wrong email/password combination!");
                self.loginstat = @"false";
                loggedInTF = false;
            }
        } failure:nil];
        [operation start];
    }
}


@end
我从来都不明白dispatch_sync是如何工作的,
知道如何等待
[loginSingleton attemptologin]完成?

attemptologin
可能是一种异步方法。您希望以这样一种方式编写Attemptologin,即当HTTP请求完成执行时,它会给您一个回调。您可以通过完成块、委托或通知来实现这一点

如果等待请求完成,最终会阻塞主线程,这将冻结用户交互,导致糟糕的用户体验

- (void)attemptToLogin:(void(^)(BOOL login))complete {
   ...
   [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        ....
       // After you get login status
       complete(your_login_status_here);
   }
}
CustomTabBarController

-(void)viewDidAppear:(BOOL)animated{
    myCustomQueue = dispatch_queue_create("com.myDomain.appName", NULL);
    loginSingleton = [LoginCheckSingleton sharedInstance];

        [loginSingleton attemptToLogin:^(loginStatus){
               if([loginStatus  isEqual: @"true"]){
                   NSLog(@"Logged In");
               }else{
                    NSLog(@"Not Logged In");
                    dispatch_async(dispatch_get_main_queue(), {
                      [self performSegueWithIdentifier:@"goToLoginView" sender:self];
                    });
               }

        }];

}

Attemptologin做什么?为什么它需要处于调度关闭状态?为什么不内联执行?我用调用的方法添加了singleton类,您可以检查它。您需要为
attemptologin
方法创建一个回调,在该方法中检查login finish之后,执行该回调。在
CustomTabBarController
中,将
if
语句移动到
attemptologin
method@Gintama你能用代码解释一下吗:-)@FadiObaji因为我无法在注释中格式化代码,所以我添加代码作为答案,你可以检查itI添加的singleton类,你能看一下吗?非常感谢!你救了我一天:)