6

更新 2、これが誰かの役に立てば幸いです。次のリンクに解決策があります: https://discussions.apple.com/thread/5498630?start=0&tstart=0、明らかにこれは iOS のバグであり、この回避策は機能します。新しい sharedPicker を作成できますが、そこから何も取得したり、閉じたりすることはできません。リンクで提供されているものを超えてフォーマットする方法がわかりません 。それに関するヘルプは大歓迎です。

したがって、私の質問は、次のコードを取得して、実際に peoplePickerNavigationControllerDidCancel: および peoplePickerNavigationController:shouldContinueAfterSelectingPerson: のコードを作成する方法です。誰かが同様のあいまいな問題を抱えている場合に備えて、元の投稿のほとんどを残しました。

// Convoluted workaround for the iPhone 4S crash
+ (ABPeoplePickerNavigationController *)sharedPeoplePicker {
    static ABPeoplePickerNavigationController *_sharedPicker = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedPicker = [[ABPeoplePickerNavigationController alloc] init];
    });
    return _sharedPicker;
}
// then later on, use 
[YourController sharedPeoplePicker].delegate = self;
// etc.

私の現在のコード:

- (BOOL)peoplePickerNavigationController:
(ABPeoplePickerNavigationController *)peoplePicker
      shouldContinueAfterSelectingPerson:(ABRecordRef)person
                                property:(ABPropertyID)property
                              identifier:(ABMultiValueIdentifier)identifier
{
    [self displayPerson:person];
    [self.navigationController dismissViewControllerAnimated:YES completion:nil];
    return NO;

}
- (void)peoplePickerNavigationControllerDidCancel:
(ABPeoplePickerNavigationController *)peoplePicker
{

    //[self dismissViewControllerAnimated:YES completion:nil];
    [self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)pick1:(id)sender
{
    ABPeoplePickerNavigationController *picker1 =[[ABPeoplePickerNavigationController alloc] init];
    picker1.peoplePickerDelegate = self;

    [self presentViewController:picker1 animated:YES completion:nil];

    x=1;
}

更新 1、このアプリは iPhone 4/4s でクラッシュしますが、シミュレーターと iPhone5 では動作します。私が作成したリークを乗り越えるのに十分な力があるだけだと思います

ABPeoplePickerNavigationControllerユーザーがアプリの連絡先を選択したり、手動で番号を入力したりできるView Controllerを備えたiOSアプリがあります。数字を手動で入力しても問題ありません。ユーザーが開いた場合:

  1. アドレス帳から新しい連絡先を選択します

  2. アプリで使用するアドレス帳から連絡先を更新します

  3. アドレス帳を開いてキャンセルします (すべてアクションを保存せずに)

その後、クラッシュせずにアプリ内の特定のビューに移動できません。この1つのView Controllerにアクセスできない理由、またはクラッシュの原因となる理由がわかりません。

5 つの異なるピッカーを使用しています。追加したい連絡先ごとに 1 つずつ、場合によっては保存します。として保存しますNSUserDefaultsが、前述のように、ピッカーの選択が保存されていなくてもクラッシュは続きます。問題なくサイドバー ナビゲーションからアプリ内のすべてのビューに移動できます。失敗したビューの唯一の違いは、サイドバーではなくメイン ビュー コントローラーの 1 つから表示されることです。

助けや考えをいただければ幸いです。これは私が書いた最初のアプリで、更新しようとして失敗しています。再び機能するようにしたいので、戻ってリファクタリングできます。

私の実装:

    - (IBAction)pick1:(id)sender
{
    ABPeoplePickerNavigationController *picker1 =
    [[ABPeoplePickerNavigationController alloc] init];
    picker1.peoplePickerDelegate = self;

    [self presentViewController:picker1 animated:YES completion:nil];
    x = 1;
}
- (IBAction)pick2:(id)sender
{
    ABPeoplePickerNavigationController *picker2 =
    [[ABPeoplePickerNavigationController alloc] init];
    picker2.peoplePickerDelegate = self;

    [self presentViewController:picker2 animated:YES completion:nil];
    x=2;
}
- (IBAction)pick3:(id)sender
{
    ABPeoplePickerNavigationController *picker3 =
    [[ABPeoplePickerNavigationController alloc] init];
    picker3.peoplePickerDelegate = self;

    [self presentViewController:picker3 animated:YES completion:nil];
    x=3;
}
- (IBAction)pick4:(id)sender
{
    ABPeoplePickerNavigationController *picker4 =
    [[ABPeoplePickerNavigationController alloc] init];
    picker4.peoplePickerDelegate = self;

    [self presentViewController:picker4 animated:YES completion:nil];
    x=4;
}
- (IBAction)pick5:(id)sender
{
    ABPeoplePickerNavigationController *picker5 =
    [[ABPeoplePickerNavigationController alloc] init];
    picker5.peoplePickerDelegate = self;

    [self presentViewController:picker5 animated:YES completion:nil];
    x=5;
}
- (void)peoplePickerNavigationControllerDidCancel:
(ABPeoplePickerNavigationController *)peoplePicker
{
    [self dismissViewControllerAnimated:YES completion:nil];
}


- (BOOL)peoplePickerNavigationController:
(ABPeoplePickerNavigationController *)peoplePicker
      shouldContinueAfterSelectingPerson:(ABRecordRef)person {

    [self displayPerson:person];
    [self.navigationController dismissViewControllerAnimated:YES completion:nil];


    return NO;
}

- (BOOL)peoplePickerNavigationController:
(ABPeoplePickerNavigationController *)peoplePicker
      shouldContinueAfterSelectingPerson:(ABRecordRef)person
                                property:(ABPropertyID)property
                              identifier:(ABMultiValueIdentifier)identifier
{
    return NO;
}
- (void)displayPerson:(ABRecordRef)person
{
    NSString* name = (__bridge_transfer NSString*)ABRecordCopyValue(person,
                                                                    kABPersonFirstNameProperty);


    NSString* phone = nil;
    ABMultiValueRef phoneNumbers = ABRecordCopyValue(person,
                                                     kABPersonPhoneProperty);
    if (ABMultiValueGetCount(phoneNumbers) > 0) {
        phone = (__bridge_transfer NSString*)
        ABMultiValueCopyValueAtIndex(phoneNumbers, 0);
    } else {
        phone = @"[None]";
    }
    if (x==1){
        firstName1.text = name;
        contact1.text = phone;
    }
    if (x==2){
        firstName2.text = name;
        contact2.text = phone;
    }
    if (x==3){
        firstName3.text = name;
        contact3.text = phone;
    }
    if (x==4){
        firstName4.text = name;
        contact4.text = phone;
    }
    if (x==5){
        firstName5.text = name;
        contact5.text = phone;
    }

}
4

3 に答える 3

3

私自身の質問に答えて申し訳ありませんが、ほとんど変更を必要としないこれに対する別の回避策は、CF Retain を使用して、私が経験していた過剰リリースを修正することです。私は人と peoplePicker を保持し、すべてが解決されました。私がこれを解決するのを手伝ってくれたすべての人に感謝します。

- (void)peoplePickerNavigationControllerDidCancel:
(ABPeoplePickerNavigationController *)peoplePicker
{

    [self.navigationController dismissViewControllerAnimated:YES completion:nil];
   CFRetain((__bridge CFTypeRef)(peoplePicker));
}
- (BOOL)peoplePickerNavigationController:
(ABPeoplePickerNavigationController *)peoplePicker
      shouldContinueAfterSelectingPerson:(ABRecordRef)person
                                property:(ABPropertyID)property
                              identifier:(ABMultiValueIdentifier)identifier
{
    [self displayPerson:person];
    [self.navigationController dismissViewControllerAnimated:YES completion:nil];
    CFRetain(person);
    CFRetain((__bridge CFTypeRef)(peoplePicker));
    return NO;

}
于 2013-11-24T22:45:32.337 に答える
1

この問題を回避していただきありがとうございます。あなたの方法#2は本当にうまくいきます!!! https://discussions.apple.com/thread/5498630?start=0&tstart=0で説明されている同様の状況があります: MKMapView は IB によってストーリーボードに配置され、IBOutlet 以外のコードはありません。ABPeoplePickerController を提示し、それを閉じることでキャンセルし、ナビゲーションによってこのビューを離れます。次に戻り、メモリの問題を取得します。却下された ABPeoplePickerController のアドレスで、ゾンビ UINavigationBar のメソッド barStyle が呼び出されました。この状況は iOS 7 (iPad 3rd 10 および iPhone 4S) でのみ発生しましたが、コードは iOS 6 (iPhone 3GS) および MKMapView との組み合わせでのみ正常に動作します。MapView の代わりに WebView でテストしたところ、すべて正常に動作しました。iOS 7 の本当のバグだと思います。宜しくお願いします Alexey

于 2013-12-07T17:18:16.690 に答える