Lmsgsendnilself

Uninhibited Soul, Free Craziness

NSNotFound思考

| Comments

  • 引子

    当我无意点开NSNotFound时,随意瞥了一眼,突然意识到其类型和之前在开发过程中的相关使用有些出入,由于之前并没有在意很多,查阅了苹果文档后,展开了关于NSNotFound的进一步思考。

  • NSNotFound是多大

      在OS X v10.5版本之前,NSNotFound的值被定义为0x7fffffff,因此对于32-bit的系统设备, NSNotFound的值就等同于NSIntegerMax。
      但是现在为了支持64-bit的系统设备,NSNotFound现在被定义为NSIntegerMax,NSIntegerMax为LONG_MAX,因此,现在32bit和64bit的设备上NSNotFound 是不一致的,前者是231-1 , 后者是263-1
      我们在NSObjCRuntime.h文件中可以看到NSNotFound的定义如下:

     static const NSInteger NSNotFound = NSIntegerMax;
    
     #define NSIntegerMax    LONG_MAX
    
  • 进一步的思考

      基于上面的说明,已知在现在的定义中NSNotFound为LONG_MAX,而对于一些情况,如下

     - (NSUInteger)indexOfObject:(ObjectType)anObject;
    
     typedef struct _NSRange {
         NSUInteger location;
         NSUInteger length;
     } NSRange;
    


      我们能够看到indexOfObject:方法的返回值和location的类型均为NSUInteger。以其中indexOfObject(该是用来判断某个元素是否在数组中存在) 作为后续的例子。
      当看到这两个对比时,我不禁疑问,假如在64设备环境开发中,某数组元素数目足够大,假如有264-1 个, 而当我们寻找某个元素所处的位置时,假如正好是第263-1 个元素,这时indexOfObject返回的是NSNotFound,代码里面根据这个逻辑做的处理却是该元素不存在,那么岂不是由于NSUInteger和NSInteger的容量不同,产生兼容性问题?
    纸上谈兵,再多也不能证明,于是写了几行例子,

         NSMutableArray * arrContainer = [[NSMutableArray alloc] init];
         @try {
         while (1) {
             [arrContainer addObject:@"aaa"];
    
         }
         } @catch (NSException * e) {
         NSLog(@"current  elements count in arrContainer:%@",arrContainer.count);
         }
    


      在代码运行一段时候后,产生crash,看crash日志发现属于内存溢出异常,这是由于现实中RAM是远远不能支撑这么大的内存申请的。在实际开发中并没有太多必要去过多担心此类上限问题。
      但是在足够大的内存理想状态下,如果保证程序不出问题,NSArray的容量上限应该是NSIntegerMax。不过开发文档中并没有任何方式告诉我们这个上限,那如果遇到此问题岂不是很容易忽视?
      额,又回到了原点,可用RAM不够。。。这是一个不现实的问题。

Comments