سؤال

هناك خطأ غريب للغاية في الكود الخاص بي .. في الواقع ، لا توجد أخطاء على الإطلاق ، فقط يبدأ تصحيح الأخطاء بإشارة "استلام البرنامج:" Exc_bad_access ". هل يستطيع أي أحد مساعدتي؟ أنا مرتبك تمامًا ... شكرًا لك.

-(NSString *)fullNameForPhone:(NSString *)ph withAlternativeText:(NSString *)text
{
    ABAddressBookRef addressBookRef = ABAddressBookCreate(); 
    NSLog(@"create addressBookRef");
    NSString *stringToReturn = text;

    CFArrayRef allPeopleRef = ABAddressBookCopyArrayOfAllPeople(addressBookRef);  
    NSLog(@"create allPeopleRef");
    CFIndex nPeople = ABAddressBookGetPersonCount(addressBookRef);  

    int i = 0;
    BOOL nameFound = NO;

    while ((i < nPeople) && (!nameFound))
    {
        ABRecordRef recordRef = CFArrayGetValueAtIndex(allPeopleRef, i);
        NSLog(@"   create recordRef");
        CFStringRef allRecordPhonesRef = ABRecordCopyValue(recordRef, kABPersonPhoneProperty);
        NSLog(@"   create allRecordPhonesRef");
        CFIndex nPhones = ABMultiValueGetCount(allRecordPhonesRef);
        int currentPhone = 0;
        for (currentPhone = 0; currentPhone < nPhones; currentPhone++) 
        {
            CFStringRef currentPhoneNumberRef = ABMultiValueCopyValueAtIndex(allRecordPhonesRef, currentPhone);
            NSLog(@"         create currentPhoneNumberRef");
            NSString *currentCleanPhoneNumber = [self cleanPhoneNumberForString:[NSString stringWithFormat:@"%@", currentPhoneNumberRef]];
            if (currentPhoneNumberRef!=NULL)
            {
                NSLog(@"         release currentPhoneNumberRef");
                CFRelease(currentPhoneNumberRef);
            }

            if ([ph isEqualToString:currentCleanPhoneNumber])
            {
                CFStringRef firstName = ABRecordCopyValue(recordRef, kABPersonFirstNameProperty);
                CFStringRef lastName = ABRecordCopyValue(recordRef, kABPersonLastNameProperty);
                NSString *fullName = [self fullNameForFirstName:[NSString stringWithFormat:@"%@", firstName] 
                                                    andLastName:[NSString stringWithFormat:@"%@", lastName]];
                if (firstName != NULL)
                    CFRelease(firstName);
                if (lastName != NULL)
                    CFRelease(lastName);
                stringToReturn = fullName;
                nameFound = YES;
                break;
            }

        }

        CFRelease(allRecordPhonesRef);
        NSLog(@"   release allRecordPhonesRef");
        CFRelease(recordRef);
        NSLog(@"   release recordRef");
        i++;
    }
    CFRelease(allPeopleRef);
    NSLog(@"release allPeopleRef");
    CFRelease(addressBookRef);
    NSLog(@"release addressBookRef");
    return stringToReturn;
}

إخراج وحدة التحكم هو:

2009-07-31 00:20:05.230 abmodular[21747:20b] create addressBookRef
2009-07-31 00:20:05.231 abmodular[21747:20b] create allPeopleRef
2009-07-31 00:20:05.231 abmodular[21747:20b]    create recordRef
2009-07-31 00:20:05.232 abmodular[21747:20b]    create allRecordPhonesRef
2009-07-31 00:20:05.232 abmodular[21747:20b]          create currentPhoneNumberRef
2009-07-31 00:20:05.232 abmodular[21747:20b]          release currentPhoneNumberRef
2009-07-31 00:20:05.232 abmodular[21747:20b]          create currentPhoneNumberRef
2009-07-31 00:20:05.233 abmodular[21747:20b]          release currentPhoneNumberRef
2009-07-31 00:20:05.233 abmodular[21747:20b]    release allRecordPhonesRef
2009-07-31 00:20:05.233 abmodular[21747:20b]    release recordRef
2009-07-31 00:20:05.233 abmodular[21747:20b]    create recordRef
2009-07-31 00:20:05.234 abmodular[21747:20b]    create allRecordPhonesRef
2009-07-31 00:20:05.234 abmodular[21747:20b]          create currentPhoneNumberRef
2009-07-31 00:20:05.234 abmodular[21747:20b]          release currentPhoneNumberRef
2009-07-31 00:20:05.234 abmodular[21747:20b]    release allRecordPhonesRef
2009-07-31 00:20:05.235 abmodular[21747:20b]    release recordRef
2009-07-31 00:20:05.235 abmodular[21747:20b] release allPeopleRef
[Session started at 2009-07-31 00:20:05 +0400.]
GNU gdb 6.3.50-20050815 (Apple version gdb-966)
....
Attaching to process 21747.
kill
quit
The Debugger has exited with status 0.(gdb) 

الضغط على مواصلة مخرجات رسالة "exc_bad_access". يظهر Xcode ، أن أحدث سلسلة تم تنفيذها في الكود الخاص بي كانت CFRelease(addressBookRef);

هل كانت مفيدة؟

المحلول

واجهت نفس القضية التي أفعل شيئًا مشابهًا ، وبناءً على مزيد من البحث ، اكتشفت أنني قد انتهت. بحسب ال مستندات الأساس الأساسية:

إذا قمت بإنشاء أو نسخ كائن الأساس الأساسي ، فيجب عليك إصداره لاحقًا عند الانتهاء منه.

قرأت أن المعنى الذي يعمل مع الكلمة GET يجب ألا يتم إصداره من قبلك. إذا قمت بذلك ، فسوف يتسبب ذلك في مشكلة في وقت لاحق عندما يحاول المالك الحقيقي إطلاقها. لذلك ، في هذه الحالة عندما تفعل:

ABRecordRef recordRef = CFArrayGetValueAtIndex(allPeopleRef, i);

و لاحقا:

CFRelease(recordRef);

أنت تصدر شيئًا ليس من المفترض أن يتم إطلاق سراحه. في وقت لاحق عندما تفعل:

CFRelease(allPeopleRef);

ستحاول المصفوفة إصدار جميع سجلاتها التي لا تعرف أنك قد أصدرت بالفعل بعضها. والنتيجة هي خطأك. من خلال التعليق على هذا الخط ، ربما تكون قد جعلت الخطأ يختفي ، لكنني أخشى أنك أنشأت تسربًا للذاكرة.

أقترح عليك عدم الاتصال CFRelease على احصل على طريقة مؤشرات واتصل بها خلق أو ينسخ مؤشرات الطريقة (قد تكون هناك استثناءات لهذه القاعدة ولكن حتى الآن تعمل بالنسبة لي).

نصائح أخرى

allpeopleerf و admintbookRef تشير إلى نفس الكائنات؟ ربما تكون النسخة ضحلة. ماذا يفعل abaddressbookcopyarrayofallpeople؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top