2

Xcodeで連絡先アプリを実行しようとしていますが、連絡先リストが表示されますが、名前をクリックするとエラーEXC_BAD_ACCESSがスローされます.NSLogで確認したところ、テーブルビュー自体にデータを入力しているときに配列にエラーが発生することがわかりました.これは私のコードです:

// として初期化された配列

@property (strong,nonatomic) NSMutableArray *filteredData,*contactAdd;

//この関数に設定された配列

-(void)reloadAddressBook
{
    self.contactAdd = [[NSMutableArray alloc]init];    
    ABAddressBookRef addressBook = ABAddressBookCreate();//ABAddressBookCreateWithOptions(NULL,NULL);
    if(ABAddressBookHasUnsavedChanges(addressBook))
    {

        ABAddressBookSave(addressBook,NULL);
    }

    NSMutableArray *allPeople = (__bridge NSMutableArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
    int nPeople = ABAddressBookGetPersonCount(addressBook);

    for(int i=0; i < nPeople; i++ )
    {
        ABRecordRef person = (__bridge ABRecordRef)([allPeople objectAtIndex:i]);

        [self.contactAdd addObject:(__bridge id)(person)];

        NSLog(@"@details %@",contactAdd);
        CFRelease(person);
    }
    CFRelease(addressBook);
}

//この関数のエラー

  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
        {
                   static NSString *cellIdentifier;


            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];


            if (cell == nil)
                {
                    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
               }

            if(isFiltered)
            {
               ABRecordRef person = (__bridge ABRecordRef)[self.filteredData objectAtIndex:indexPath.row];
                NSString *tweet=[[NSString stringWithFormat:@"%@", ABRecordCopyValue(person, kABPersonFirstNameProperty)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
                [cell.textLabel setText:tweet];
                CFRelease(person);

            }
            else
            {
                ABRecordRef person = (__bridge ABRecordRef)([self.contactAdd objectAtIndex:indexPath.row]);
                NSLog(@"%@",person);
                NSString *tweet=[[NSString stringWithFormat:@"%@", ABRecordCopyValue(person, kABPersonFirstNameProperty)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
                [cell.textLabel setText:tweet];
                CFRelease(person);
                NSLog(@"%@",indexPath);
// I have 4 contacts currently and error occurs here on 4th time and when I continue error occurs on 2nd time
                NSLog(@"@details %@",contactAdd); 
}
return cell;
}

//実行時にここでエラーを取得

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    ABPersonViewController *currentPersonView=[[ABPersonViewController alloc]init];

    ABRecordRef person;
    if(isFiltered)
        person=(__bridge ABRecordRef)([self.filteredData objectAtIndex:indexPath.row]);
    else
        person=(__bridge ABRecordRef)([self.contactAdd objectAtIndex:indexPath.row]);//error here

    currentPersonView.displayedPerson=person;
    currentPersonView.allowsEditing=YES;
    currentPersonView.allowsActions=YES;
    [self.navigationController pushViewController:currentPersonView animated:YES];

}

//NSLog

2013-08-01 13:11:12.715 連絡先[7722:207] 2 つのインデックス [0, 0]

現在の言語: auto; 現在、objective-c 2013-08-01 13:11:26.614 Contacts[7722:207] @details ( "CPRecord: 0xba1b340 ABPerson", "CPRecord: 0xba1c870 ABPerson", "CPRecord: 0xba1c160 ABPerson", "CPRecord: 0xba1c990 ABPerson" )

2013-08-01 13:11:26.616 連絡先[7722:207]

2013-08-01 13:11:26.617 連絡先[7722:207] 2 つのインデックス [0、1]

2013-08-01 13:11:27.566 連絡先[7722:207] @詳細 (「CPRecord: 0xba1b340 ABPerson」、「CPRecord: 0xba1c870 ABPerson」、「CPRecord: 0xba1c160 ABPerson」、「CPRecord: 0xba1c990 ABPerson」) 2013-08 -01 13:11:27.567 連絡先[7722:207] 2013-08-01 13:11:27.568 連絡先[7722:207] 2 つのインデックス [0、2] (gdb)

4

4 に答える 4

0

CFArray を使用してこの問題を解決することができました。これは、他の誰かが必要とする場合のコードです。(iphoneシミュレーター5.0)

-(void)reloadAddressBook
{

    if(addressBook)
        CFBridgingRelease(addressBook);
    addressBook = ABAddressBookCreate();
    person=ABAddressBookCopyDefaultSource(addressBook);
    contactAdd=ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(self.addressBook,self.person,0);
    }

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSString *cellIdentifier;

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];


        if (cell == nil)
            {
                cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
           }

        if(isFiltered)
        {
           self.person = CFArrayGetValueAtIndex(self.filteredData,indexPath.row);
            NSString *tweet=[[NSString stringWithFormat:@"%@",(__bridge_transfer NSString *)ABRecordCopyCompositeName(self.person)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

            [cell.textLabel setText:tweet];


        }
        else
        {
            self.person = CFArrayGetValueAtIndex(self.contactAdd, indexPath.row);
            NSString *tweet=[[NSString stringWithFormat:@"%@",(__bridge_transfer NSString *)ABRecordCopyCompositeName(self.person)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
             [cell.textLabel setText:tweet];           
        }


        return cell;
    }

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if(isFiltered)
       return CFArrayGetCount(self.filteredData);
    else
    {
        if(CFArrayGetCount(self.contactAdd)==0)
        {
            UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"Message"
                                                              message:@"Empty Contacts"
                                                             delegate:nil
                                                    cancelButtonTitle:@"OK"
                                                    otherButtonTitles:nil];
            [message show];
        }

        return CFArrayGetCount(self.contactAdd);
    }
    }
于 2013-08-08T12:57:32.890 に答える
0

最初にあなたの値を入れてくださいcellIdentifier

static NSString *cellIdentifier = @"CellIdentifier";

于 2013-08-01T07:59:26.343 に答える
0

値なしで放置しないでくださいstatic NSString *cellIdentifier;。例:

static NSString *cellIdentifier = @"SimpleTableCell"

を .m ファイルに追加したらcellIdentifier、ストーリーボードの tableView セルに追加したことを確認してください

この画像を参照してください: http://www.appcoda.com/wp-content/uploads/2012/04/SimpleTable-Cell-Identifier.jpg

(申し訳ありませんが、さらにスタックオーバーフローを進めるまで画像を埋め込むことはできません!)

于 2013-08-01T08:13:58.003 に答える
0

contactAddアレイがどのように管理されているかを確認する必要があります。contactAdd配列は 100 個のオブジェクトを取り込む目的で作成されていますが、連絡先は 4 つしかありません。

self.contactAdd = [[NSMutableArray alloc]initWithCapacity:100];

これには、実際に存在する連絡先の数のみを入力する必要があります。ただし、これらの最初の 100 スロットに関係なく、オブジェクトも配列に追加しています。

[self.contactAdd addObject:(__bridge id)(person)];

現在、あなたが人を選択しようとすると、あなたがコメントで指摘したように、実際に操作するオブジェクトがない可能性があります。

person=(__bridge ABRecordRef)([self.contactAdd objectAtIndex:indexPath.row]);//error here

あなたのコードを考えると、単に配列を作成し、後で自然に人口を増やすだけです:

self.contactAdd = [[NSMutableArray alloc]init];

また、ポピュレーション中には、あまり意味のないことがいくつか発生します。最初に人物オブジェクトを追加しますが、次に人物オブジェクトを移動しますか?

[self.contactAdd addObject:(__bridge id)(person)];
[self.contactAdd replaceObjectAtIndex:i withObject:(__bridge id)(person)];

これは元の 100 スロットに関係していると思いますが、そのマジック ナンバーを削除すると、このステップも削除されます。

また、保持していないオブジェクトを解放しています。

ABRecordRef person = (__bridge ABRecordRef)([allPeople objectAtIndex:i]);
//. . . 
CFRelease(person);

ここで何が達成されているかをよりよく理解するには、テーブル ビューの操作に関するドキュメントを確認する必要があると思います。しかし、考慮すべきことの1つは、これを行うことです...

self.contactAdd = (__bridge NSMutableArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);

...与えられたオブジェクトを使用しているためです。

他の最初の 2 つの回答も正しくcellIdentifier、作成時に文字列を入力する必要があります。

于 2013-08-01T10:13:22.407 に答える