情景: 使用MethodSwizzle 实现对数组、字典 等系统方法的安全校验。显然能达到预期效果,但实际发现当

键盘显示的情况下  home app 进入后台,再单击app  图标 切换回前台时 发生crash :

[UIKeyboardLayoutStar release]: message sent to deallocated instance

UIKeyboardLayoutStar 是键盘上的布局的视图吧,

整个工程都在ARC下 构建,很奇怪,而且必须。

信息:

http://huang.sh/2015/02/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84crash-uikeyboardlayoutstar-release/

http://code4app.com/ios/DurexKit%E5%AE%89%E5%85%A8%E5%B7%A5%E5%85%B7%E5%8C%85/5325b421933bf0463d8b49ec

其中都有提到DurexKit  原理都是一样的,上面提到原因是替换了 NSArray的objectAtIndex: 方法,

不过在我的项目原因是替换了NSMutableArray 的objectAtIndex:( NSMutableArray和 NSArray 的objectAtIndex:都有替换,单独替换 NSArray 的objectAtIndex:方法则不会引起crash)

解决方案:给 添加非ARC 支持,并改写实现

有提到:。。貌似 arc 有时也不一定可靠。

----------------------2015.3.23-----更新--0.0--继续填坑啊----------------------------------

话说使用 语法糖初始化 数组和 字典 真的好方便。。。@{....}  @[...]  但是很容易埋雷。。大多数里面存的都是变量 在代码里。so , 也需要校验 。

最初使用 MethodSwizzle 很嗨皮啊,首先涉及可变参数在替换的方法里 试图使用NSInvocation 来解决 传递多个参数的问题,最后 莫名crash 。。你可以试试。

再说说数组和字典里的类簇(工厂模式):

http://blog.sunnyxx.com/2014/12/18/class-cluster/

后来发现如果你用语法糖 初始化数组 crash 信息如下:

'*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from xx

 解决方案使用静态方法 + objc_msgSend 来实现:

#import <objc/message.h>

#define CurrentClass objc_getClass("__NSArrayI")

static id array_safe_initWithObjects(id self, SEL _cmd, const id* objects,unsigned int count){
id orignialResult = nil;
@try {
orignialResult = objc_msgSend(self, @selector(array_safe_initWithObjects:count:),objects,count);
}
@catch (NSException *exception) {
DDLogDebug(@"=__NSPlaceholderArray===BUSTED!");
}
return orignialResult ;
} @implementation NSArray (SafeCheck) +(void)load{
//添加
[CurrentClass swizzleInstanceSelector:@selector(objectAtIndex:) withNewSelector:@selector(safeObjectsAtIndex:)]; [objc_getClass("__NSPlaceholderArray") swizzleSelector: @selector(initWithObjects:count:) withNewSelector:@selector(array_safe_initWithObjects:count:) andNewIMP:(IMP)&array_safe_initWithObjects];
}
+ (void) swizzleSelector:(SEL)originalSelector
withNewSelector:(SEL)newSelector
andNewIMP:(IMP)imp{ Method originMethod = class_getInstanceMethod(self, originalSelector);
const char * methodEncodeType = method_getTypeEncoding(originMethod);
BOOL methodAdded = class_addMethod(self, newSelector, imp, methodEncodeType); if (methodAdded) {
Method newMethod = class_getInstanceMethod(self,newSelector);
method_exchangeImplementations(newMethod, originMethod);
}else{
DDLogDebug(@"=====faile=");
}
}

在运行时中会维护 selector 和 IMP 对应关系表。

同理字典也一样呢可以使用这种方法 添加语法糖校验。

#import <objc/message.h>

static id dic_safe_initWithObjects(id self, SEL _cmd, const id* objects, const id* keys, unsigned int count) {

    id orignialResult = nil;

    @try {
orignialResult = objc_msgSend(self, @selector(dic_safe_initWithObjects:forKeys:count:), objects, keys, count);
}
@catch (NSException *exception) {
DDLogDebug(@"__NSPlaceholderDictionary===BUSTED!");
} return orignialResult;
} @implementation NSDictionary (SafeCheck)
+(void)load{
[objc_getClass("__NSPlaceholderDictionary") swizzleSelector:@selector(initWithObjects:forKeys:count:) withNewSelector:@selector(dic_safe_initWithObjects:forKeys:count:) andNewIMP:(IMP)&dic_safe_initWithObjects];
}

runtime MethodSwizzle 实践之 奇怪crash : [UIKeyboardLayoutStar release]: message sent to deallocated instance的更多相关文章

  1. -[UIKeyboardLayoutStar release]: message sent to deallocated instance 0x7fbe49120000

    __NSArrayM objectAtIndex: 取消swizzle 只有debug的时候会报错,发布的时候是好的,所以可以不用改

  2. -[UIKeyboardLayoutStar release]: message sent to deallocated instance

    网上大家都说是因为替换了系统的objextAtIndex方法,但是为了减少应用崩溃的可能,是要进行Hook的,所以不想取消Hook. 解决办法,关掉键盘进入后台. - (void)applicatio ...

  3. [CALayer release]: message sent to deallocated instance iOS内存过度释放问题

    [CALayer release]: message sent to deallocated instance iOS内存过度释放问题 解决方式: 1:先找到过度释放的 内存指针 开启-僵尸模式:xc ...

  4. [CALayer release]: message sent to deallocated instance

    遇到此问题时,查看以下类的dealloc方法中是否有过度释放. 可以在release前先判断以下对象是否还存在. -(void)dealloc { if (!m_tableView) [m_table ...

  5. runtime MethodSwizzle 实践之扩展 NIAttributedLabel

    runtime MethodeSwizzle 提供 简单的方法交换已知类的  Method IMP. Method 可以是 外部可访问的 public 或者 private Method .所谓的属性 ...

  6. iPhone开发过程中调试多次Release问题 message sent to deallocated

    初级:第一步   为程序添加符号断点 malloc_error_break  方法如下. 目标效果:让程序崩溃时跳转到出错到那一行.但是往往达不到这个效果.不行就继续往下看. At times, wh ...

  7. 【kudu pk parquet】runtime filter实践

    已经有好一阵子没有写博文了,今天给大家带来一篇最近一段时间开发相关的文章:在impala和kudu上支持runtime filter. 大家搜索下实践者社区,可以发现前面已经有好几位同学写了这个主题的 ...

  8. [20180124]奇怪的SQL*Net message from dblink.txt

    [20180124]奇怪的SQL*Net message from dblink.txt --//生产系统出现大量的SQL*Net message from dblink事件,自己分析看看. 1.环境 ...

  9. 《CMake实践》笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE

    <CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...

随机推荐

  1. text-indent

    <div class="top wd"> <div class="con fl "><a href="#"&g ...

  2. Android照片墙应用实现,再多的图片也不怕崩溃

    本文首发于CSDN博客,转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9526203 照片墙这种功能现在应该算是挺常见了,在很多应用 ...

  3. 对于C++窗口编译一闪而过的解决方法 (DEV CPP下)

    对于C++窗口编译一闪而过的解决方法 首先来看一个简单的程序(编译环境为 DEV C++.):  #include <iostream>  int main()  {      std:: ...

  4. 3D扫描系统的构建(待处理)

    1. http://www.zhihu.com/question/32143353 是否可以 DIY 一个 3D 扫描仪或者开源 3D 扫描项目? 详细的原理介绍 2. http://www.csks ...

  5. poj 3635/hdu 1676 Full Tank? 车辆加油+最短路

    http://acm.hdu.edu.cn/showproblem.php?pid=1676 给出一张图,n<=1000,m<=10000. 有一辆车想从图的一个地方到达另外一个地方,每个 ...

  6. Jquery插件实现点击获取验证码后60秒内禁止重新获取

    通过jquery.cookie.js插件可以快速实现“点击获取验证码后60秒内禁止重新获取(防刷新)”的功能 先到官网(http://plugins.jquery.com/cookie/ )下载coo ...

  7. SQLite数据库在本地可以写,发布到服务器就不能写

    用SQLite开发的一个Web Api,提供Json和Jsonp格式的数据,在本地使用vs2012开发并运行时,数据库的读写均正常. 但发布到Windows Server 2008 + IIS 7.5 ...

  8. 在Mac OS X上用自己编译出的CoreCLR运行.NET程序

    当昨天被Mac OS X上无法编译CoreCLR的问题困扰时(详见Mac OS X上尝试编译CoreCLR源代码),后来发现这个难题竟然被神人@kangaroo给解决了,连CoreCLR的微软开发人员 ...

  9. 容易答错的JS笔试题

    1,考察this var length = 10 function fn(){     alert(this.length) } var obj = {     length: 5,     meth ...

  10. [MSSQL2005]再看CTE

    个人认为CTE最大的做点是可以处理树状存储的数据了 例如类似这样设计的数据表,ID,ParentID这样的设计使用CTE就非常方便,原因就是CTE可以自引用,达到类似递归的效果 那么问题来了,如何使用 ...