*** 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雖好可以實現自己想要的功能,但是一定要注意關鍵字的問題,一不留神,問題查找相當的難受。自己的寫的代碼還好說問題分析還快,特別是別人寫的代碼,你要看懂還要理解,最煩的就是沒註釋,哎,程序員的痛啊!!!!

 通過一系類問題追蹤,自己已找到了解決此問題方法了,如果斷點跟蹤也沒辦法找到異常問題所在,可以試試分類方法重寫類的實現,然後再看看堆棧信息,可能會有所發現!!!

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章