iOS - error:unrecognized selector sent to class 導入第三方SDK .a后不識別,運行崩潰


今天將app統計的.a靜態庫包含到一個app應用中,調試時報下面的錯誤:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSDictionary dictionaryWithJSONString:error:]:unrecognized selector sent to class 0x235e7ec'

unrecognized selector sent to class 0x235e7ec'

*** First throw call stack:

(

0   CoreFoundation                      0x022195e4 __exceptionPreprocess + 180

1   libobjc.A.dylib                     0x01f288b6 objc_exception_throw + 44

2   CoreFoundation                      0x022b67a3 +[NSObject(NSObject) doesNotRecognizeSelector:] + 275

3   CoreFoundation                      0x0220990b ___forwarding___ + 1019

4   CoreFoundation                      0x022094ee _CF_forwarding_prep_0 + 14


...

10  Foundation                          0x01b80597 -[NSThread main] + 76

11  Foundation                          0x01b804f6 __NSThread__main__ + 1275

12  libsystem_c.dylib                   0x02d625b7 _pthread_start + 344

13  libsystem_c.dylib                   0x02d4cdce thread_start + 34

)

libc++abi.dylib: terminating with uncaught exception of type NSException

 

糾結了好久,定位代碼錯誤位置如下:

 

  • NSString *retString = [network SendData:url data:requestDictionary];
  •     NSError *error = nil;
  •     NSDictionary *retDictionary = [ NSDictionary dictionaryWithJSONString:retString error:&error];
  •     if(!error)
  •     {
  •         ret.flag = [[retDictionary objectForKey:@\"flag\" ] intValue];
  •         ret.msg = [retDictionary objectForKey:@\"msg\"];
  •     }
  •     return ret;
  •     }

推斷原因是:NSDictionary 是內嵌對象,但是dictionaryWithJSONString  另一個自定義對象的方法。為什么要用與NSDictionary  相同的名稱,原因就是要返回NSDictionary對象。

 

自定義對象代碼如下:

 

  • @implementation NSDictionary (NSDictionary_JSONExtensions)
  • + (id)dictionaryWithJSONData:(NSData *)inData error:(NSError **)outError
  •     {
  •     return([[CJSONDeserializer deserializer] deserialize:inData error:outError]);
  •     }
  • + (id)dictionaryWithJSONString:(NSString *)inJSON error:(NSError **)outError;
  •     {
  •     NSData *theData = [inJSON dataUsingEncoding:NSUTF8StringEncoding];
  •     return([self dictionaryWithJSONData:theData error:outError]);
  •     }
  • @end

所以,推斷xcode沒有正確解析代碼,把dictionaryWithJSONString 方法錯誤認為是內嵌對象NSDictionary 的內部方法,但NSDictionary 沒有這個方法,所以調試的時候,就找不到該方法的實現,報出錯誤信息:unrecognized selector sent to class 0x235e7ec'

 

推斷出問題的可能原因后,很有可能是工程的setting信息有問題。於是開始一個一個參數過,一開始以為是Search Paths的各種路徑配置錯誤,后來驗證不是。否則編譯都應該過不去。

於是,將范圍定在Build Settings下的Linking的參數列表。馬上有一個參數映入眼簾:Other Linker Flags,沒有設置。通過google,查詢相關說明:

 

-all_load Loads all members of static archive libraries.

 

-ObjC Loads all members of static archive libraries that implement an Objective-C class or category.

 

-force_load (path_to_archive) Loads all members of the specified static archive library. Note: -all_load forces all members of all archives to be loaded. This option allows you to target a specific archive.

 

翻譯過來就是-all_load就是會加載靜態庫文件中的所有成員,-ObjC就是會加載靜態庫文件中實現一個類或者分類的所有成員,-force_load(包的路徑)就是會加載指定路徑的靜態庫文件中的所有成員。所以對於使用runtime時候的反射調用的方法應該使用這三個中的一個進行link,以保證所有的類都可以加載到內存中供程序動態調用

 

到這里,基本就明白了,就是這個參數沒有設置的原因。將Other Linker Flags=-ObjC,再重新調試,運行成功!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM