这是我的登录按钮:
- (IBAction)signInButtonAction:(id)sender
{
if ([self.phoneNumberTextField.text length] == 0 || [self.passwordTextField.text length] == 0) {
[self initializeAlertControllerForOneButtonWithTitle:@"Alert!" withMessage:kEmptyTextFieldAlertMSG withYesButtonTitle:@"Ok" withYesButtonAction:nil];
} else {
if ([self alreadyRegisteredPhoneNumber] == YES) {
if ([self.password isEqualToString:self.passwordTextField.text]) {
[self goToHomeViewController];
} else {
[self initializeAlertControllerForOneButtonWithTitle:@"Wrong Password!" withMessage:kWrongPasswordMSG withYesButtonTitle:@"Ok" withYesButtonAction:nil];
}
} else {
[self initializeAlertControllerForOneButtonWithTitle:@"Alert!" withMessage:kSignInPhoneNumberDoesnotExistMSG withYesButtonTitle:@"Ok" withYesButtonAction:nil];
}
}
}
这是我已经注册的电话号码方法,在这里我只是检查给定的电话号码是否已注册。
- (BOOL)alreadyRegisteredPhoneNumber
{
[self.activityIndicator startAnimating];
__block BOOL isThisPhoneNumberRegistered = NO;
BlockWeakSelf weakSelf = self;
SignInViewController *strongSelf = weakSelf;
dispatch_sync(dispatch_queue_create("mySyncQueue", NULL), ^{
NSString *PhoneNumberWithIsoCountryCode = [NSString stringWithFormat:@"%@%@", strongSelf.countryCode, strongSelf.phoneNumberTextField.text];
strongSelf.userModelClass = [[RetrieveDataClass class] retrieveUserInfoForPhoneNumber:PhoneNumberWithIsoCountryCode];
if ([strongSelf.userModelClass.phone_number length] != 0) {
strongSelf.phoneNumber = strongSelf.userModelClass.phone_number;
strongSelf.password = strongSelf.userModelClass.password;
isThisPhoneNumberRegistered = YES;
[strongSelf.activityIndicator stopAnimating];
}
});
return isThisPhoneNumberRegistered;
}
使用此方法的问题是,当我按“登录”按钮时,
activityIndicator
不会出现。否则它会以同步方式工作,这是完美的。activityIndicator
未出现的原因是我必须更新dispatch_async(dispatch_get_main_queue()
中与UI相关的更改(或否?)。但是,如果我这样重新排列我的代码:- (BOOL)alreadyRegisteredPhoneNumber
{
[self.activityIndicator startAnimating];
__block BOOL isThisPhoneNumberRegistered = NO;
BlockWeakSelf weakSelf = self;
SignInViewController *strongSelf = weakSelf;
dispatch_async(dispatch_get_main_queue(), ^{
dispatch_sync(dispatch_queue_create("mySyncQueue", NULL), ^{
NSString *PhoneNumberWithIsoCountryCode = [NSString stringWithFormat:@"%@%@", strongSelf.countryCode, strongSelf.phoneNumberTextField.text];
strongSelf.userModelClass = [[RetrieveDataClass class] retrieveUserInfoForPhoneNumber:PhoneNumberWithIsoCountryCode];
if ([strongSelf.userModelClass.phone_number length] != 0) {
strongSelf.phoneNumber = strongSelf.userModelClass.phone_number;
strongSelf.password = strongSelf.userModelClass.password;
isThisPhoneNumberRegistered = YES;
[strongSelf.activityIndicator stopAnimating];
}
});
});
return isThisPhoneNumberRegistered;
}
activityIndicator
显示完美,但是它总是返回isThisPhoneNumberRegistered = NO
,因为它以异步方式工作,而我的更新isThisPhoneNumberRegistered = YES
最近又返回了。因此,如果需要,这种情况下:
用户按下登录按钮
然后出现
activityIndicator
我的服务器调用(
strongSelf.userModelClass = [[RetrieveDataClass class] retrieveUserInfoForPhoneNumber:PhoneNumberWithIsoCountryCode];
)检索数据并根据其设置isThisPhoneNumberRegistered = YES
或isThisPhoneNumberRegistered = NO
然后将值恢复为
If else
条件if ([self alreadyRegisteredPhoneNumber] == YES) {
if ([self.password isEqualToString:self.passwordTextField.text]) {
[self goToHomeViewController];
} else {
[self initializeAlertControllerForOneButtonWithTitle:@"Wrong Password!" withMessage:kWrongPasswordMSG withYesButtonTitle:@"Ok" withYesButtonAction:nil];
}
我该怎么做?
非常感谢。
最佳答案
通常,您希望使用Asynch进程,以便可以“做其他事情”,例如更新UI,以使用户知道发生了什么事情。
为此,您需要分离逻辑。尝试用以下术语来思考:
signInButtonAction {
if no phone or password entered
show alert
else
showAnimatedSpinner()
checkForRegisteredPhone()
}
checkForRegisteredPhone {
// start your async check phone number process
// on return from the async call,
if !registered
hide spinner
show kSignInPhoneNumberDoesnotExistMSG message
else
checkForMatchingPassword()
}
checkForMatchingPassword {
if !passwordsMatch
hide spinner
show "passwords don't match" message
else
hide spinner
goToHomeViewController
}
换句话说,不要编写您的代码,这样它就会“锁定”在一个进程中,从而防止发生其他任何事情。