*** Assertion failure in +[PLManagedObjectContext __prepareEntityPropertyLookups]问题

如题,当程序崩溃报错为:*** Assertion failure in +[PLManagedObjectContext __prepareEntityPropertyLookups], /BuildRoot/Library/Caches/com.apple.xbs/Sources/PhotoLibraryServices_Sim/MobileSlideShow-3442.11.230/Sources/PLManagedObjectContext.m:1218    ???一脸蒙B

程序就是简简单单调用系统的UIImagePickerController ,获取相册图片功能。

第一次调用都没问题,下次再次弹出UIImagePickerController,一点击图片就会崩溃,如果选择cancel都不会出现问题。

第一直觉就是找到崩溃的入口,开启断点跟踪,在堆栈信息列表找也没找到有用的信息!

 花了大半天时间,也没发现疑点之处。然后度娘,Google搜索都没有好的信息可以解决此问题。

开始怀疑 iOS UIImagePickerController访问相册权限问题,查了查info.plist文件的都有相关的配置

是不是授权问题返回,采用的线程有问题,自己也参照SdWebImage的安全线程写法做了一个宏定义,保证现在一定在主线程执行,结果还是没有处理问题。

prepareEntityPropertyLookups 函数名称信息中是不是UIImagePickerController在获取图片信息,查询属性信息耗时,自己又把UIImagePickerController对象dismiss,于是看了看UIImagePickerController委托信息,picker 不能自己dismiss自己,

难道自己的代码写的有问题,只要自己用到授权机制

dismissViewControllerAnimated的动画写成NO,或者不用info数据,第一次正常使用UIImagePickerController,第二次肯定崩溃。

 

又查了查PLManagedObjectContext 到底是什么文件,Google一把,看到了PLManagedObjectContext是IOS私有库PhotoLibraryServices.framework 的文件,难道IOS系统有bug。

系统出问题了,这个不是瞎扯嘛,后来看了看报错的前缀 “Assertion failure ” ==> 断言失败,难道程序开启断言功能

查看了一下原来Xcode在debug下默认开启断言功能,以为自己找到问题的所在,结果呢?

我把断言关闭了,结果还是一样,难道代码里面自己加了断言的宏定义?

结果一样也没找到问题所在,时间就这样慢慢的耗下去,难道自己写的代码有问题。

于是把UIImagePickerController相关的代码移植到新的项目中测试,结果测试一点都没问题,自己肯定自己的代码没问题,问题

处在自己的工程里面,可能默写的代码写的问题,太隐蔽了,没法找到。

 

自己的想了想有没有更好办法定位呢?于是想到了分类方法可以覆盖原类的方法,于是准备干起来,重写PLManagedObjectContext 的prepareEntityPropertyLookups方法

想法虽好但是呢?正如前面写的一样,这个PhotoLibraryServices是系统私有库,没法使用。咋办呢?

这样不行,那样也不行,困死本宝宝啦。

于是干脆学习NSLog宏定义方式,debug能输出log,release不能输出,于是让NSAssert在debug与release都不输出

效果依然不得解,咋办,那就看看NSAssert具体调用了什么方法。

 

NSAssertionHandler 是Foundation下NSException类文件中定义的类。

依旧分类的方式实现NSAssertionHandler方法,采用nil发送消息不会对程序崩溃,结果测试怎样呢?

 耶!居然通过了,程序也没崩溃,一切都正常啦,问题终于得解。但是这并不是解决的问题的关键啊,断言功能就这样被我废了不好吧,程序也不是这样干的。

于是就断点跟踪,看看程序堆栈类别到底什么情况引起的断言问题。

0x11faa5d47 <+920>:  callq  *%r15
    0x11faa5d4a <+923>:  movq   %rax, %r10
    0x11faa5d4d <+926>:  movq   0x4e503c(%rip), %rsi      ; "handleFailureInMethod:object:file:lineNumber:description:"
    0x11faa5d54 <+933>:  subq   $0x8, %rsp
    0x11faa5d58 <+937>:  leaq   0x429bb9(%rip), %r11      ; @"%@ (%lu) has too many attributes to treat as a single bitfield"
    0x11faa5d5f <+944>:  movl   $0x4c2, %r9d              ; imm = 0x4C2 
    0x11faa5d65 <+950>:  xorl   %eax, %eax
    0x11faa5d67 <+952>:  movq   -0x58(%rbp), %rdi

这个到底是什么意思呢?

难道数据库CoreData有问题?因为PLManagedObjectContext集成与NSManagedObjectContext

@interface PLManagedObjectContext : NSManagedObjectContext

再看看自己的堆栈数据结果被我找到问题所在啦

userInfo 属性问题,于是代码搜一把

问题终于找到啦,原来开发人员在写NSObject分类时候,利用runtime机制自定义的userInfo属性。

于是把这些代码注释掉,程序就正常啦。 

总结:

runtime虽好可以实现自己想要的功能,但是一定要注意关键字的问题,一不留神,问题查找相当的难受。自己的写的代码还好说问题分析还快,特别是别人写的代码,你要看懂还要理解,最烦的就是没注释,哎,程序员的痛啊!!!!

 通过一系类问题追踪,自己已找到了解决此问题方法了,如果断点跟踪也没办法找到异常问题所在,可以试试分类方法重写类的实现,然后再看看堆栈信息,可能会有所发现!!!

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值