小萝莉说Crash(一):Unrecognized selector sent to instance xxxx
写在前面的:分享一篇文,原文地址:小萝莉说Crash(一):Unrecognized selector sent to instance xxxx
---------------------------------------------------------------------------------------------------------------------------------------------
大家好,我是来自Bugly Crash实验室的小萝莉(害羞ing),很高兴能和大家一起讨论关于移动终端App的Crash问题及解决方法。
在上次的“精神哥讲Crash”系列中,精神哥给大家分享了小白埋坑,让人泪奔的惨痛经历。这或许会让广大机器猿大呼多么痛的领悟,而以为高大上的水果猿也庆幸还是水果靠谱。然而,coding路上,哪有不挖坑的小白,哪有不被坑的小猿呢?
从本周开始,萝莉会定期给大家分享苹果猿(iOS移动开发者)挖坑和埋坑的一些经历。
今天,首先要给大家讲的是一个入(xiao)门(bai)必(mai)现(keng)的Crash类型 - NSInvalidArgumentException
的一个错误问题unrecognized selector sent to instance xxxx
Crash基本介绍
错误类型 | NSInvalidArgumentException |
错误原因 | unrecognized selector sent to instance xxxx |
错误释义 | 给实体对象发送了不认识的消息,即对象调用方法出错(方法不存在或对象已被release) |
错误基本原因 | Objective-C的方法调用其实是基于消息传递的机制,并且是动态编译。因此在编译阶段不会进行类和方法的绑定,而是在运行时执行绑定操作。当类的方法没有实现或对象被提前release时,这个问题会在运行时表现出来,从而导致App崩溃。 |
影响力 | 出现率及出错量均在前10,基本上算是小白必遇 |
下面,我们就通常会出现此类异常的几种常见场景做一个简单分析。
出错场景分析
1.一个符号引发的血案
示例:
...
// 定义后台加载数据任务
[obj performSelectorInBackground:@selector(loadDataOnBackground:) withObject:0];
...// 实现selector方法
- (void)loadDataOnBackground{
...
}
错误分析:
定义的 selector 方法为带参数的形式,注意方法名后有冒号“:”,而代码中实现的为无参的方法。
正确的方法实现应如下样式:
- (void)loadDataOnBackground:(id) sender{...
}
在代码中我们通常对Objective-C
对象设置selector
方法实现事件监听、延时操作或异步操作,但定义后忘记实现方法或方法名书写错误都是常有的事,尤其是在代码量变大,代码结构和注释不够完善的情况下。
此类问题在编译阶段会有警告信息,只要稍加留意就可以修正。
开发者建议:
* 确定 selector 定义使用的流程,即定义后马上实现,并检查是否带参数(方法名是否“:”结尾)* 合理使用 #pragma 标记组织代码结构* 不要简单忽略编译过程的警告选项,编译阶段的警告在运行时就可能造成应用崩溃
2.“虚伪”的代理者
示例:
// 定义delegate发送请求
@protocol RequestDelegate <NSObject>
- (BOOL)sendRequest:(id) req;
@end// 发送请求管理器
@implementation RequestManager
-(BOOL)sendPostRequest:(id) req { ... if (delegate) {...return [delegate sendRequest:req]; } ... return NO;
}
错误分析:
delegate 是在开发复杂App时必定会用到的机制,通常地,delegate 被定义为id
类型,其被设置的实例可能没有实现 RequestDelegate 方法,此时调用sendRequest方法就会出现崩溃。
一般规范的做法是在调用前使用respondsToSelector:(SEL) aSelector
方法进行判断,如下:
-(BOOL)sendPostRequest:(id) req {...if (delegate && [delegate respondsToSelector:@selector(sendRequest:)]) {...return [delegate sendRequest:req];}...return NO;
}
开发者建议:
* delegate 方法调用前进行 respondsToSelector 判断* 实现 delegate 时,立即实现对应的 delegate 方法并添加相应注释
3.对象都去哪儿了
示例:
// 定义属性与同名变量 @interface RequestManager : NSObject {id delegate; } @property (nonatomic, retain) id delegate;- (id)initWithDelegate:(id) _dele; @end@implementation RequestManager @synthesize delegate;- (id)initWithDelegate:(id) _dele{self = [super init];if (self) {delegate = _dele; // 没有添加引用计数,应该使用self.delegate = _dele;}return self; } @end
错误分析:
在初始化方法中,没有调用setter
方法对属性赋值,因此没有添加引用计数,这样在使用self.delegate
时,有可能已经被release
了,此时应用就会崩溃。
这种场景是出现此类问题最多的一种情况,尤其是在非ARC模式的项目中,对象的retain
和release
手动控制,更易导致此类问题。
开发者建议:
* 属性和成员变量不要重名定义,合理使用 synthesize 生成属性的 setter 和 getter 方法* 变量的 retain 和 release 要谨慎,建议采用安全 release 方法,即 release 的对象置为 nil
小结
以上就是给大家分享的关于unrecognized selector sent to instance xxxx
异常的内容,其列举的场景并不能完全覆盖我们开发过程中碰到此类问题的所有情况。但万变不离其宗,此类问题的核心就是指向对象的地址出现问题,导致方法调用不成功。
因此,规范的使用API和Objective-C
的机制是避免此类问题的前提,而对于此类问题,一般也是建议开发人员在调式阶段能够发现并解决,而非简单规避。当然,为了应用在发布后的稳定性,我们也可以通过forwardInvocation
机制避免应用出现崩溃。
后续小萝莉也会跟大家分享如何调式定位此类问题及forwardInvocation
的使用方法。
感谢大家的阅读和关注,敬请期待下次腾讯Bugly-Crash实验室推出的“小萝莉说Crash”和“精神哥讲Crash”系列文。
============================
如果你觉得文章还行,请分享到你的朋友圈,让知识的火种燃烧起来吧
如果你想了解更多Crash监控内容,欢迎关注我们的公众号:腾讯Bugly,我们将定期为您分享
如果你想知道自己产品有多少Crash,请让你的产品接入最专业的Crash跟踪平台腾讯Bugly(http://bugly.qq.com)
如果你对Crash实验室有什么建议或问题,欢迎在公众号里中直接反馈
小萝莉说Crash(一):Unrecognized selector sent to instance xxxx相关推荐
- 小萝莉说Crash(二): Unrecognized selector xxx 之 ForwardInvocation
2015年不急不忙地到来,小萝莉为大家奉上新年礼包,祝大家新年快乐,希望开发GGMM们新一年的开发工作更加顺利.安心! 在上篇的分享中,小萝莉给大家介绍了一个入门必现的应用崩溃问题 -- Unreco ...
- 【小萝莉说Crash】第一期:Unrecognized selector sent to instance xxxx
大家好,我是来自Bugly Crash实验室的小萝莉(害羞ing),很高兴能和大家一起讨论关于移动终端App的Crash问题及解决方法. 在上次的"精神哥讲Crash"系列中,精神 ...
- 【小萝莉说Crash】第二期:Unrecognized selector xxx 之 ForwardInvocation
2015年不急不忙地到来,小萝莉为大家奉上新年礼包,祝大家新年快乐,希望开发GGMM们新一年的开发工作更加顺利.安心! ^_^ 在上篇的分享中,小萝莉给大家介绍了一个入门必现的应用崩溃问题 -- Un ...
- ios unrecognized selector sent to instance出现的原因和解决方案
概述:造成unrecognized selector sent to instance iphone,大部分情况下是因为对象被提前release了,在你心里不希望他release的情况下,指针还在,对 ...
- 静态库调用中“unrecognized selector sent to instance”错误
在开发调用静态库的中,出现 "unrecognized selector sent to instance 0x2b5f90"的错误 -[__NSCFConstantString ...
- 错误:-[UIKBBlurredKeyView candidateList]: unrecognized selector sent to instance
错误 app 在线上有个崩溃的问题, crash原因为-[UIKBBlurredKeyView candidateList]: unrecognized selector sent to instan ...
- IOS微信API异常:unrecognized selector sent to instance 0x17005c9b0'
2019独角兽企业重金招聘Python工程师标准>>> 开发IOS整合微信API的时候,在运行程序的过程中可能会在注册你的APPID的时候抛出此异常而导致程序崩溃. 异常描述 [76 ...
- 【iOS】使用storyboard界面跳转报错:unrecognized selector sent to instance 0x7
使用storyboard直接model界面跳转的时候出现报错:unrecognized selector sent to instance 0x7... 网上查了相似的问题但是依旧没有找到解决方法,后 ...
- IOS微信API异常:unrecognized selector sent to instance 0x17005c9b0‘
IOS微信API异常:unrecognized selector sent to instance 0x17005c9b0' 参考文章: (1)IOS微信API异常:unrecognized sele ...
最新文章
- RHEL7OSP-6.0的openstack云主机发放
- FIR基本型仿真_03
- 瑞柏匡丞_移动互联的发展现状与未来
- 一个程序设计试题:读取2维字符数组,判断出表示的数字
- Python模块(8)-sklearn 简易使用教程
- Tomcat控制台输出到文件
- 大学教师读博后违约离职,校方索赔79万!
- [leetcode] 140. 单词拆分 II
- 1.1.2获取和控制线程状态(Getting and Seeting Thread State)
- 跨应用的访问 contentprovider
- Robocode 超级机器人 “波”统计瞄准算法
- 面向法务编程|如何对接支付宝新产品满足法务要求:助力法务反洗钱反诈骗
- 2017中国银行业发展趋势报告
- matlab全桥电路设计,全桥变换电路的Matlab仿真及实验装置开发.pdf
- DVWA Insecure CAPTCHA(不安全的验证码)全等级
- 瀑布流布局 js定位
- 论一个程序猿的自我修养!
- lol最克制诺手的英雄_LOL:最克制诺手的三个英雄,剑姬上榜,第一能打得诺手出不了塔...
- [原创]WIA 学习笔记
- 在开发环境使用 TiUP安装TiDB集群
热门文章
- 2021年的Gartner云基础设施和平台服务魔力象限有什么不一样?
- 拼多多后台x4.0监控mysql_11、ABPZero系列教程之拼多多卖家工具 拼团提醒功能页面实现...
- 将有朋自远方来,不亦乐乎
- 现代基准测试程序种类以及使用方法
- vue开发APP使用微信分享和QQ分享功能
- Postman配置token进行测试
- vim配置http://www.cnblogs.com/ma6174/archive/2011/12/10/2283393.html
- Excel制作热力图
- -source 1.6 中不支持 diamond 运算符
- Matplotlib:设置坐标轴范围,刻度,位置,自定义刻度名称,添加数据标签