0

以下のコードを実行して、アドレス帳からすべての連絡先の電話番号を取得しようとしました:

  ABAddressBookRef addressBook = ABAddressBookCreate();
  NSArray *arrayOfPeople = 
  (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);    
  NSUInteger index = 0;
  allContactsPhoneNumber = [[NSMutableArray alloc] init];

  for(index = 0; index<=([arrayOfPeople count]-1); index++){

    ABRecordRef currentPerson = 
    (__bridge ABRecordRef)[arrayOfPeople objectAtIndex:index];

    NSArray *phones = 
    (__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(
    ABRecordCopyValue(currentPerson, kABPersonPhoneProperty));

    // Make sure that the selected contact has one phone at least filled in.
    if ([phones count] > 0) {
      // We'll use the first phone number only here.
      // In a real app, it's up to you to play around with the returned values and pick the necessary value.
      [allContactsPhoneNumber addObject:[phones objectAtIndex:0]];
    }
    else{
      [allContactsPhoneNumber addObject:@"No phone number was set."];
    }
  }

ただし、iOS 6 ではうまく機能しますが、iOS 5 ではうまく機能しません。次のコードでクラッシュしました。

ABRecordRef currentPerson = 
(__bridge ABRecordRef)[arrayOfPeople objectAtIndex:index];

出力は次のように表示されます。

*** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray objectAtIndex:]: index (0) beyond bounds (0)'

なぜクラッシュしたのか誰にもアドバイスがありますか?ありがとう!

4

1 に答える 1

2

これは iOS5/iOS6 に依存する問題ではなく、テスト環境が異なる場合の問題です。1 つのケース (1 つのシミュレーターだと思います) では、アドレス帳に連絡先があり、別の場合にはありません。

ただし、がゼロforの場合、ループ内のテストは失敗します。これは、 unsignedである を返し、を減算するとアンダーフローが作成されるためです (符号なし整数として解釈されると、代わりに整数の最大値が得られるため、が負であり、もちろん、符号なし整数は正の整数のみを格納できます)。[arrayOfPeople count]countNSUInteger-10UL-1-1

したがって、連絡先がなく[arrayOfPeople count]、ゼロの場合は、とにかくループに入りfor、空の人の配列でインデックス 0 のオブジェクトを取得しようとするとクラッシュします。


forからループ内の条件を置き換えます

for(index = 0; index<=([arrayOfPeople count]-1); index++)

for(index = 0; index<[arrayOfPeople count]; index++)

forまた、アドレス帳に連絡先がない場合は、アンダーフローせず、ループに入らないため、クラッシュは解消されるはずです。

于 2012-10-11T08:30:45.430 に答える