zoukankan      html  css  js  c++  java
  • (转)ios error:unrecognized selector sent to class

    转自:http://blog.itpub.net/12231606/viewspace-1081952/

    今天将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


    纠结了好久,定位代码错误位置如下:

    1. NSString *retString = [network SendData:url data:requestDictionary];
    2.     NSError *error = nil;
    3.     NSDictionary *retDictionary = [ NSDictionary dictionaryWithJSONString:retString error:&error];
    4.     if(!error)
    5.     {
    6.         ret.flag = [[retDictionary objectForKey:@"flag" ] intValue];
    7.         ret.msg = [retDictionary objectForKey:@"msg"];
    8.     }
    9.     return ret;
    10.     }

    推断原因是:NSDictionary 是内嵌对象,但是dictionaryWithJSONString  另一个自定义对象的方法。为什么要用与NSDictionary  相同的名称,原因就是要返回NSDictionary 对象。

    自定义对象代码如下:

    1. @implementation NSDictionary (NSDictionary_JSONExtensions)
    2. + (id)dictionaryWithJSONData:(NSData *)inData error:(NSError **)outError
    3.     {
    4.     return([[CJSONDeserializer deserializer] deserialize:inData error:outError]);
    5.     }
    6. + (id)dictionaryWithJSONString:(NSString *)inJSON error:(NSError **)outError;
    7.     {
    8.     NSData *theData = [inJSON dataUsingEncoding:NSUTF8StringEncoding];
    9.     return([self dictionaryWithJSONData:theData error:outError]);
    10.     }
    11. @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,再重新调试,运行成功!!

  • 相关阅读:
    Android 3.0 r1 API中文文档(108) —— ExpandableListAdapter
    Android 3.0 r1 API中文文档(113) ——SlidingDrawer
    Android 3.0 r1 API中文文档(105) —— ViewParent
    Android 中文 API (102)—— CursorAdapter
    Android开发者指南(4) —— Application Fundamentals
    Android开发者指南(1) —— Android Debug Bridge(adb)
    Android中文API(115)——AudioFormat
    Android中文API(116)——TableLayout
    Android开发者指南(3) —— Other Tools
    Android中文API (110) —— CursorTreeAdapter
  • 原文地址:https://www.cnblogs.com/guoxiaoqian/p/4026388.html
Copyright © 2011-2022 走看看