• Stars
    star
    661
  • Rank 68,192 (Top 2 %)
  • Language
    Objective-C
  • License
    MIT License
  • Created over 6 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

强大的防止crash框架,不改变原代码支持KVO自释放,可以检测到dealloc时未释放的kvo,等19种crash

中文说明

LSSafeProtector 是一个可快速集成但功能强大的防止crash库,不改变原代码支持KVO自释放,可以检测到dealloc时未释放的kvo,等19种crash,使用Objective-C编写.

须知

LSSafeProtector 基于 "Xcode 7.3 , iOS 7+ 和ARC ,请使用最新正式版来编译LSSafeProtector,旧版本的Xcode可能有效,但不保证会出现一些兼容性问题。

CocoaPods

推荐使用 CocoaPods 安装。

  1. 在 Podfile 中添加 pod 'LSSafeProtector'
  2. 执行 pod installpod update。(如搜索不到,请更新pod仓库pod repo update)
  3. 导入 "LSSafeProtector.h"

手动安装

通过 Clone or download 下载 LSSafeProtector 文件夹内的所有内容。 将 LSSafeProtector 内的源文件添加(拖放)到你的工程。 将 NSMutableArray+MRCSafe.m文件 设置为 -fno-objc-arc 导入 LSSafeProtector.h

使用

切记 切记 切记!!!

[LSSafeProtector openSafeProtectorWithIsDebug]一定要在其他SDK之前调用

  • 通过如下方式开启防止闪退功能(不包含KVO防护,想要开启KVO防护可以使用下面的方法),debug模式会打印crash日志,同时会利用断言来让程序闪退,也会回调block,达到测试环境及时发现及时修改,Release模式既不打印也不会断言闪退,会回调block,自己可以上传exception到bugly(注意线上环境isDebug一定要设置为NO)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //注意线上环境isDebug一定要设置为NO)
    [LSSafeProtector openSafeProtectorWithIsDebug:YES block:^(NSException *exception, LSSafeProtectorCrashType crashType) {
    //[Bugly reportException:exception];

    //此方法相对于上面的方法,好处在于bugly后台查看bug崩溃位置时,不用点击跟踪数据,再点击crash_attach.log,查看里面的额外信息来查看崩溃位置
    [Bugly reportExceptionWithCategory:3 name:exception.name reason:[NSString stringWithFormat:@"%@  崩溃位置:%@",exception.reason,exception.userInfo[@"location"]] callStack:@[exception.userInfo[@"callStackSymbols"]] extraInfo:exception.userInfo terminateApp:NO];
    }];
    //打开KVO添加,移除的日志信息
    [LSSafeProtector setLogEnable:YES];
    [Bugly startWithAppId:@"5c825b6c8d"];
    //···调用其他SDK或初始化东西
    return YES;
}

  • 当然你也可以设置防止指定类型的crash,但还是建议直接使用上面方法,防止所有类型的crash来防止闪退
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [LSSafeProtector openSafeProtectorWithIsDebug:isDebug types:LSSafeProtectorCrashTypeNSArrayContainer|LSSafeProtectorCrashTypeNSDictionaryContainer block:^(NSException *exception, LSSafeProtectorCrashType crashType) {
    //[Bugly reportException:exception];
    //此方法方便在bugly后台查看bug崩溃位置,而不用点击跟踪数据,再点击crash_attach.log来查看崩溃位置
    [Bugly reportExceptionWithCategory:3 name:exception.name reason:[NSString stringWithFormat:@"%@  崩溃位置:%@",exception.reason,exception.userInfo[@"location"]] callStack:@[exception.userInfo[@"callStackSymbols"]] extraInfo:exception.userInfo terminateApp:NO];
    }];
    //打开KVO添加,移除的日志信息
    [LSSafeProtector setLogEnable:YES];
    [Bugly startWithAppId:@"5c825b6c8d"];
    //···调用其他SDK或初始化东西
    return YES;
}

下面是防止崩溃的效果

  • 可导致崩溃的代码
NSMutableArray *a1=[NSMutableArray array];
a1[10];
  • 若没有防止崩溃,则会直接崩溃,如下图所示 image

  • 用本框架来防止崩溃,则会捕获到崩溃信息并打印出来(测试环境会利用断言闪退达到及时发现及时修改),如下图 image

  • 来看看block回调回来的信息都有哪些 image

  • KVO 检测到dealloc时有没remove的keyPath image

  • 更多的使用用例可以看Demo工程演示

目前支持以下类型crash

  • 1、LSSafeProtectorCrashTypeSelector
1.捕获到未实现方法时,自动将消息转发,避免crash
  • 2、LSSafeProtectorCrashTypeKVO
1.移除未注册的观察者 会crash
2.重复移除观察者 会crash
3.添加了观察者但没有实现observeValueForKeyPath:ofObject:change:context:方法
4.添加移除keypath=nil;
5.添加移除observer=nil;
6.dealloc时自动移除观察者,俗称自释放KVO
  • 3、LSSafeProtectorCrashTypeNSArray
1. NSArray的快速创建方式 NSArray *array = @[@"chenfanfang", @"AvoidCrash"];//调用的是3的方法
2. + (instancetype)arrayWithObjects:(const ObjectType _Nonnull [_Nonnull])objects count:(NSUInteger)cnt;调用的也是3的方法
3. - (instancetype)initWithObjects:(const ObjectType _Nonnull [_Nullable])objects count
4. - (id)objectAtIndex:(NSUInteger)index
******  注意 *****
[__NSCFArray objectAtIndex]不能防止crash,如果交换了会导致其他crash,所以这里不做交换

  • 4、LSSafeProtectorCrashTypeNSMutableArray
1. - (void)addObject:(ObjectType)anObject(实际调用insertObject:)
2. - (void)insertObject:(ObjectType)anObject atIndex:(NSUInteger)index;
3. - (id)objectAtIndex:(NSUInteger)index( 包含   array[index] 形式)
4. - (void)removeObjectAtIndex:(NSUInteger)index
5. - (void)replaceObjectAtIndex:(NSUInteger)index
6. - (void)removeObjectsInRange:(NSRange)range
7. - (void)replaceObjectsInRange:(NSRange)range withObjectsFromArray:(NSArray*)otherArray;
  • 5、LSSafeProtectorCrashTypeNSDictionary
1.+ (instancetype)dictionaryWithObjects:(const ObjectType _Nonnull [_Nullable])objects forKeys:(const KeyType <NSCopying> _Nonnull [_Nullable])keys count:(NSUInteger)cnt会调用2中的方法
2.- (instancetype)initWithObjects:(const ObjectType _Nonnull [_Nullable])objects forKeys:(const KeyType _Nonnull [_Nullable])keys count:(NSUInteger)cnt;
3. @{@"key1":@"value1",@"key2":@"value2"}也会调用2中的方法
4. - (instancetype)initWithObjects:(NSArray<ObjectType> *)objects forKeys:(NSArray<KeyType <NSCopying>> *)keys;
  • 6、LSSafeProtectorCrashTypeNSMutableDictionary
1.直接调用 setObject:forKey
2.通过下标方式赋值的时候,value为nil不会崩溃
iOS11之前会调用 setObject:forKey
iOS11之后(含11)  setObject:forKeyedSubscript:
3.removeObjectForKey
  • 7、LSSafeProtectorCrashTypeNSStirng
1. initWithString
2. hasPrefix
3. hasSuffix
4. substringFromIndex:(NSUInteger)from
5. substringToIndex:(NSUInteger)to {
6. substringWithRange:(NSRange)range {
7. characterAtIndex:(NSUInteger)index
8. stringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement 实际上调用的是9方法
9. stringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement options:(NSStringCompareOptions)options range:(NSRange)searchRange
10. stringByReplacingCharactersInRange:(NSRange)range withString:(NSString *)replacement
  • 8、LSSafeProtectorCrashTypeNSMutableString
//除NSString的一些方法外又额外避免了一些方法crash
1.- (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)aString;
2.- (NSUInteger)replaceOccurrencesOfString:(NSString *)target withString:(NSString *)replacement options:(NSStringCompareOptions)options range:(NSRange)searchRange;
3.- (void)insertString:(NSString *)aString atIndex:(NSUInteger)loc;
4.- (void)deleteCharactersInRange:(NSRange)range;
5.- (void)appendString:(NSString *)aString;
6.- (void)setString:(NSString *)aString;
  • 9、LSSafeProtectorCrashTypeNSAttributedString
1.- (instancetype)initWithString:(NSString *)str;
2.- (instancetype)initWithString:(NSString *)str attributes:(nullable NSDictionary<NSAttributedStringKey, id> *)attrs;
3.- (instancetype)initWithAttributedString:(NSAttributedString *)attrStr;
  • 10、LSSafeProtectorCrashTypeNSMutableAttributedString
1.- (instancetype)initWithString:(NSString *)str;
2.- (instancetype)initWithString:(NSString *)str attributes:(nullable NSDictionary<NSAttributedStringKey, id> *)attrs;
3.- (instancetype)initWithAttributedString:(NSAttributedString *)attrStr;

4. - (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str;
5.- (void)setAttributes:(nullable NSDictionary<NSAttributedStringKey, id> *)attrs range:(NSRange)range;

6.- (void)addAttribute:(NSAttributedStringKey)name value:(id)value range:(NSRange)range;
7.- (void)addAttributes:(NSDictionary<NSAttributedStringKey, id> *)attrs range:(NSRange)range;
8.- (void)removeAttribute:(NSAttributedStringKey)name range:(NSRange)range;

9.- (void)replaceCharactersInRange:(NSRange)range withAttributedString:(NSAttributedString *)attrString;
10.- (void)insertAttributedString:(NSAttributedString *)attrString atIndex:(NSUInteger)loc;
11.- (void)appendAttributedString:(NSAttributedString *)attrString;
12.- (void)deleteCharactersInRange:(NSRange)range;
13.- (void)setAttributedString:(NSAttributedString *)attrString;

  • 11、LSSafeProtectorCrashTypeNSNotificationCenter
1. dealloc时自动将self从通知中心移除

  • 12、LSSafeProtectorCrashTypeNSUserDefaults
可避免以下方法  key=nil时的crash
1.objectForKey:
2.stringForKey:
3.arrayForKey:
4.dataForKey:
5.URLForKey:
6.stringArrayForKey:
7.floatForKey:
8.doubleForKey:
9.integerForKey:
10.boolForKey:
11.setObject:forKey:

  • 13、LSSafeProtectorCrashTypeNSCache
1.setObject:forKey:
2.setObject:forKey:cost:

  • 14、LSSafeProtectorCrashTypeNSSet
1.setWithObject:
2.(instancetype)initWithObjects:(ObjectType)firstObj
3.setWithObjects:(ObjectType)firstObj

  • 15、LSSafeProtectorCrashTypeNSMutableSet
1.setWithObject:
2.(instancetype)initWithObjects:(ObjectType)firstObj
3.setWithObjects:(ObjectType)firstObj
4.addObject:
5.removeObject:

  • 16、LSSafeProtectorCrashTypeNSData
1.subdataWithRange:
2.rangeOfData:options:range:

  • 17、LSSafeProtectorCrashTypeNSMutableData
1.subdataWithRange:
2.rangeOfData:options:range:
3.resetBytesInRange:
4.replaceBytesInRange:withBytes:
5.replaceBytesInRange:withBytes:length:

  • 18、LSSafeProtectorCrashTypeNSOrderedSet
1.orderedSetWithSet
2.initWithObjects:count:
3.objectAtIndex:

  • 19、LSSafeProtectorCrashTypeNSMutableOrderedSet
1. - (void)addObject:(ObjectType)anObject
2. - (void)insertObject:(ObjectType)anObject atIndex:(NSUInteger)index;
3. - (id)objectAtIndex:(NSUInteger)index( 包含  set[index]  形式  )
4. - (void)removeObjectAtIndex:(NSUInteger)index
5. - (void)replaceObjectAtIndex:(NSUInteger)index

更新记录

  • 2018.9.13 更新日志
添加对以下类的支持
NSUserDefaults 
NSCache
NSSet 
NSMutableSet
NSOrderedSet
NSMutableOrderedSet
NSData
NSMutableData

  • 2018.11.13 更新
将__NSCFArray的hook使用MRC编写
NSMutableArray增加以下方法的hook
- (void)replaceObjectsInRange:(NSRange)range withObjectsFromArray:(NSArray*)otherArray;

联系

  • 如果使用过程中遇到什么问题或有什么建议可以联系我,我会在收到后尽快回复您

  • QQ群 :922898729

  • email at: [email protected]

  • email at: [email protected]

注意

  • 最近好多人问我为什么线上环境崩溃位置定位不到,这是因为导出ipa包安装,崩溃位置是定位不到的,即使Debug模式导出ipa也是定位不到,和正式测试没关系,是由于ipa包安装的crash日志是非源码,无法直接分析定位,必须符号化。xcode安装是源码安装。具体符号化步骤可以参照网上,这里不做过多说明,本框架的主旨是防止crash,而不是定位crash

许可

LSSafeProtector 使用 MIT 许可证,详情可见 LICENSE 文件。

More Repositories

1

LSNavigationController

导航栏背景色可以统一设置,每一个控制器导航栏背景色还可以自己单独设置不影响统一设置的界面,采用自定义交互动画实现淘宝,京东等软件当下最流行的导航控制器效果,比其他实现方式每一个控制器都包装一个导航控制器性能更好,使用方法更贴合系统使用方法
Objective-C
76
star
2

LSPlayer

一个仿UC浏览器视频页播放界面的实现,视屏框位置完全由用户来定义,支持拖拽,缩放,全屏,由于网络不好播放失败进行了处理
Objective-C
70
star
3

LSNewsDetailWebviewContainer

今日头条 腾讯新闻 网易新闻等,上面网页webview,下面tableview界面,轻松集成
Objective-C
67
star
4

LSCreateModel

mac app根据json字符串创建模型类 自动判断类型
Objective-C
37
star
5

LSPanSwiper

几行代码实现交互式push pop动画,可以随意自定义push,pop动画
Objective-C
28
star
6

LSChangeLocation

仅适用于修改iOS微信朋友圈,空间照片的位置,经纬度可以自己随便写
Objective-C
25
star
7

LSLaunchAD

一行代码实现启动广告页
Objective-C
21
star
8

LSStatusBarHUD

一个类似映客,qq音乐,新版qq状态栏上的提示效果-可以按自己的需求自定义样式
Objective-C
14
star
9

LSActionSheet

目前主流actionSheet效果,类似微信,微博
Objective-C
14
star
10

LSBuild

命令打包 一键打包 以及上传到app-store,蒲公英,fir, 然后分发邮件,以及ipa重签名(自动获取提交日志)
Shell
12
star
11

LSProgressHud

一款模仿UBER的加载动画,使用方法类似MBProgressHud
Objective-C
10
star
12

LSConsole

日志实时显示以及快速修改沙盒值方便测试,还有摇一摇显示隐藏功能
Objective-C
7
star
13

LSPerfectMusic

一款简单的音乐播放器,有断点下载,列表管理,播放队列,电台,搜索音乐,及酷狗滑动效果的实现,由于网上找的api不好用了,所以歌曲搜索不到了
Objective-C
6
star
14

LSEmptyTableView

两行代码实现当tableview无内容时自动显示提示语,一键设置断网提示,头部可拉伸放大图片等功能
Objective-C
5
star
15

LSPerfectVideoLive

至美直播 简单实用IJKMoviePlayer和LFLiveKit实现rtmp 拉流和推流
C
3
star
16

LSiOSShell

iOS shell相关脚本
Python
2
star
17

LSLeetcode_OC

leetcode算法题集锦
Objective-C++
2
star
18

LSAppOrderFiles

基于LLVM二进制重排
Objective-C
1
star
19

LSApplePayDemo

applePay集成简单demo
Objective-C
1
star
20

LSClickLikeAnimation

仿映客点赞动画
Objective-C
1
star
21

LSTreeLoading

类似支付宝蚂蚁森林 加载动画 小数在生长
Objective-C
1
star
22

LSCustomPush

支付宝语音播报
Objective-C
1
star
23

LSDynamicAction

摩拜贴纸动画
Objective-C
1
star