提问人:programcode 提问时间:3/28/2021 最后编辑:programcode 更新时间:3/29/2021 访问量:276
尝试从 objects[1]' 插入 NIL 对象
attempt to insert nil object from objects[1]'
问:
我想通过选项卡栏控制器显示 ChatViewController。应用的当前初始视图是加载 ChatViewController 的 NavigationController。加载 ChatViewController 时,它会检查是否调用了“joinedchat”方法。如果没有,它会显示 LoginViewController 以允许用户对 ChatViewController 进行身份验证。当用户进行身份验证时,LoginViewController 将关闭。
LoginViewController 和 ComposeViewController 是显示在 ChatViewController 顶部的模式视图控制器。
我想在情节提要的稍后时间点访问此 ChatViewController,同时将其保留为 rootviewcontroller,以便它仍然可以保留它用于类的数据模型,以预期它使用的方法。$_POST
如果尚未调用,我没有显示 LoginViewController,而是显示不同的视图控制器。大约 4 个视图控制器之后,在用户执行不同的进程后,我使用选项卡栏控制器再次访问 LoginViewController。当我尝试调用 postUpdateRequest 方法来访问 ChatViewController 时,应用程序崩溃,调试器中显示输出:joinedchat
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[1]'
我怀疑这是因为该应用程序使用严格的数据模型来设置 snd 存储用户将从 LoginViewController 通过 .有谁知道使用此数据对用户进行身份验证的任何方法?postJoinRequest
AppDelegate.m - didRegisterForRemoteNotificationsWithDeviceToken
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
UINavigationController *navigationController = (UINavigationController*)_window.rootViewController;
ChatViewController *chatViewController = (ChatViewController*)[navigationController.viewControllers objectAtIndex:0];
DataModel *dataModel = chatViewController.dataModel;
NSString* oldToken = [dataModel deviceToken];
NSString* newToken = [deviceToken description];
newToken = [newToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
newToken = [newToken stringByReplacingOccurrencesOfString:@" " withString:@""];
NSLog(@"My token is: %@", newToken);
[dataModel setDeviceToken:newToken];
if ([dataModel joinedChat] && ![newToken isEqualToString:oldToken])
{
[self postUpdateRequest];
}
}
AppDelegate.m - PostUpdateRequest (英文)
- (void)postUpdateRequest
{
UINavigationController *navigationController = (UINavigationController*)_window.rootViewController;
ChatViewController *chatViewController = (ChatViewController*)[navigationController.viewControllers objectAtIndex:0];
DataModel *dataModel = chatViewController.dataModel;
NSDictionary *params = @{@"cmd":@"update",
@"user_id":[dataModel userId],
@"token":[dataModel deviceToken]};
AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:ServerApiURL]];
[client
postPath:@"/api.php"
parameters:params
success:nil failure:nil];
}
DataModel.m - 初始值设定项
+ (void)initialize
{
if (self == [DataModel class])
{
// Register default values for our settings
[[NSUserDefaults standardUserDefaults] registerDefaults:
@{NicknameKey: @"",
SecretCodeKey: @"",
JoinedChatKey: @0,
DeviceTokenKey: @"0",
UserId:@""}];
}
}
DataModel.m - 用户 Id
- (NSString*)userId
{
NSString *userId = [[NSUserDefaults standardUserDefaults] stringForKey:UserId];
if (userId == nil || userId.length == 0) {
userId = [[[NSUUID UUID] UUIDString] stringByReplacingOccurrencesOfString:@"-" withString:@""];
[[NSUserDefaults standardUserDefaults] setObject:userId forKey:UserId];
}
return userId;
}
LoginViewController.h (更新)
@class DataModel;
// The Login screen lets the user register a nickname and chat room
@interface LoginViewController : UIViewController
@property (nonatomic, assign) DataModel* dataModel;
@property (nonatomic, strong) AFHTTPClient *client;
@end
LoginViewController.m - postJoinRequest 和 loginAction
- (void)postJoinRequest
{
MBProgressHUD* hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = NSLocalizedString(@"Connecting", nil);
NSDictionary *params = @{@"cmd":@"join",
@"user_id":[_dataModel userId],
@"token":[_dataModel deviceToken],
@"name":[_dataModel nickname],
@"code":[_dataModel secretCode]};
[_client postPath:@"/api.php"
parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
if ([self isViewLoaded]) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
if([operation.response statusCode] != 200) {
ShowErrorAlert(NSLocalizedString(@"There was an error communicating with the server", nil));
} else {
[self userDidJoin];
}
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
if ([self isViewLoaded]) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
ShowErrorAlert([error localizedDescription]);
}
}];
}
- (IBAction)loginAction
{
if (self.nicknameTextField.text.length == 0)
{
ShowErrorAlert(NSLocalizedString(@"Fill in your nickname", nil));
return;
}
if (self.secretCodeTextField.text.length == 0)
{
ShowErrorAlert(NSLocalizedString(@"Fill in a secret code", nil));
return;
}
[self.dataModel setNickname:self.nicknameTextField.text];
[self.dataModel setSecretCode:self.secretCodeTextField.text];
// Hide the keyboard
[self.nicknameTextField resignFirstResponder];
[self.secretCodeTextField resignFirstResponder];
[self postJoinRequest];
}
ChatViewController.h (更新)
#import "ComposeViewController.h"
@class DataModel;
// The main screen of the app. It shows the history of all messages that
// this user has sent and received. It also opens the Compose screen when
// the user wants to send a new message.
@interface ChatViewController : UITableViewController <ComposeDelegate>
@property (nonatomic, strong, readonly) DataModel* dataModel;
@end
更新终端输出
答: 暂无答案
评论
@"user_id":[dataModel userId]
[dataModel userId]
NSData
NSString
NSString* newToken = [deviceToken description];
didRegisterForRemoteNotification
Update
appdelegate.m
postJoinRequest
LoginViewControlelr