一、背景简介
这个可能对于网上很多大神来讲,是一个很简单的问题,但是因为它在我的工作中被我碰见了,所以我就把这个Mark一下。主要是发送通知的时候发送了一个字典字符串,但是这个用反序列化问题解析成字典导致crash。
报错如下:
报错:reason: '-[__NSCFString bytes]: unrecognized selector sent to instance 0x60800008e1a0'
二、问题分析与解决
1>贴代码:
ViewController.m实现文件
#import "ViewController.h"
#import "KODModalViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(didReciveNotification:) name:@"kNotificationName" object:nil];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
KODModalViewController *mvc = [[KODModalViewController alloc]init];
[self presentViewController:mvc animated:YES completion:nil];
}
- (void)didReciveNotification:(NSNotification *)info{
NSDictionary *urseInfo = info.userInfo;
NSError *error;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:urseInfo[@"obj"] options:0 error:&error];
if (dict) {
NSLog(@"%@",dict);
}else{
NSLog(@"%@",error);
}
}
@end
KODModalViewController.h代码:
#import <UIKit/UIKit.h>
@interface KODModalViewController : UIViewController
@end
KODModalViewController.m代码如下:
#import "KODModalViewController.h"
@interface KODModalViewController ()
@end
@implementation KODModalViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self addBtn];
}
- (void)addBtn{
UIButton *btn = [[UIButton alloc]init];
btn.frame = CGRectMake(0, 300, 200, 50);
CGPoint btnCenter = CGPointMake(self.view.center.x, btn.frame.origin.y + 25);
btn.center = btnCenter;
btn.backgroundColor = [UIColor orangeColor];
[self.view addSubview:btn];
[btn setTitle:@"点我发送通知" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(didClickBtn) forControlEvents:UIControlEventTouchUpInside];
}
- (void)didClickBtn{
NSDictionary *info = @{@"name":@"zhangsan",@"goodsID":@"10100101"};
NSError *parseError = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:info options:NSJSONWritingPrettyPrinted error:&parseError];
NSString *objString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSDictionary *dict = @{@"obj":objString};
[[NSNotificationCenter defaultCenter] postNotificationName:@"kNotificationName" object:self userInfo:dict];
}
2>问题分析:
我们点击ViewController的touchesBegan方法modal出KODModalViewController,然后点击KODModalViewController控制器上的按钮然后发送一个通知,ViewController接收到数据之后处理数据。
崩溃之后我们看了下源码发现我们在解析的NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:urseInfo[@"obj"] options:0 error:&error];这个方法中传入的urseInfo[@"obj"其实是一个字符串,然而JSONObjectWithData方法是需要传入一个NSData,只有NSData才有bytes这个方法,但是NSString是没有这个方法的,所以报“-[__NSCFString bytes]: unrecognized selector sent to instance 0x60800008e1a0”.
3>解决方案:
我们只需要把这个字符串转成NSData作为参数然后传给反序列化方法即可了。
- (void)didReciveNotification:(NSNotification *)info{
NSDictionary *urseInfo = info.userInfo;
NSString *infoString = urseInfo[@"obj"];
NSData *data = [infoString dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (dict) {
NSLog(@"%@",dict);
}else{
NSLog(@"%@",error);
}
}
效果截图:
问题解决,以上!