iphone - كسر على EXC_BAD_ACCESS في XCode؟




objective-c debugging exc-bad-access (9)

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

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

يساعد بشكل خاص في مؤشرات الترابط الخلفية عند debriber أحياناً cra craing على أي معلومات مفيدة.

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

if(getenv("NSZombieEnabled") || getenv("NSAutoreleaseFreedObjectCheckEnabled"))
  NSLog(@"NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled enabled!");

إذا كنت بحاجة إلى المساعدة في العثور على السطر الصحيح ، قم بإنشاء و Debug ( CMD-Y ) بدلاً من إنشاء وتشغيل ( CMD-R ). عند تعطل التطبيق ، سيعرض لك مصحح الأخطاء أي خط وبالتعاون مع NSZombieEnabled ، سيكون بمقدورك معرفة السبب بالضبط.

أنا جديد على تطوير iPhone و XCode بشكل عام وليس لدي أي فكرة عن كيفية بدء استكشاف أخطاء EXC_BAD_ACCESS . كيف يمكنني الحصول على XCode لكسر في السطر الدقيق الذي يسبب الخطأ؟

يبدو أنني لا أستطيع الحصول على XCode للتوقف على الخط الذي يسبب المشكلة ، لكنني أرى الأسطر التالية في وحدة التحكم الخاصة بي في تصحيح الأخطاء:

Sun Oct 25 15:12:14 jasonsmacbook TestProject [1289]: CGContextSetStrokeColorWithColor: context invalid

Sun Oct 25 15:12:14 jasonsmacbook TestProject [1289]: CGContextSetLineWidth: سياق غير صالح

Sun Oct 25 15:12:14 jasonsmacbook TestProject [1289]: CGContextAddPath: context invalid

Sun Oct 25 15:12:14 jasonsmacbook TestProject [1289]: CGContextDrawPath: سياق غير صالح

2009-10-25 15: 12: 14.680 LanderTest [1289: 207] *** - [CFArray objectAtIndex:]: تم إرسال الرسالة إلى مثيل تم إلغاء تخصيصه 0x3c4e610

الآن ، أحاول رسم السياق الذي UIGraphicsGetCurrentContext() من UIGraphicsGetCurrentContext() وتمريره إلى الكائن الذي أريد رسمه.

مزيد من التجارب والخطأ التصحيح ووجدت أن NSMutableArray لدي ممتلكات لفي صفي كان زومبي. ذهبت إلى وظيفة init للفصل ، وهنا الرمز الذي كنت أستخدمه:

if ((self = [super init])) {
        NSMutableArray *array = [NSMutableArray array];
        self.terrainBlocks = array;
        [array release];
    }
    return self;    
}

أزلت سطر [array release] ولم يعد يعطيني إشارة EXC_BAD_ACCESS ، ولكني الآن مرتبك حول سبب EXC_BAD_ACCESS ذلك. ظننت أنه عندما استخدمت العقار ، احتفظت به تلقائيًا ، وبالتالي يجب أن أفرج عنه من داخل init حتى لا يكون هناك تسريب. أنا في حيرة من أمري حول كيفية عمل هذا وكلّ الأساتذة والأسئلة التي قرأتها فقط أربطني أكثر حول كيفيّة تعيين الخصائص ضمن طريقة ابتدائي. يبدو أنه لا يوجد توافق في الآراء حول الطريقة الأفضل.


إجابة جديدة لمؤشر ترابط قديم ... في XCode 4 ، الطريقة الأكثر فعالية لتشخيص استثناءات EXC_BAD_ACCESS هي استخدام الأدوات لتوصيف التطبيق الخاص بك (من XCode انقر فوق Product / Profile واختر Zombies). سيساعدك ذلك في تحديد الرسائل المرسلة إلى الكائنات التي تم إلغاء تخصيصها.


حول صفيف الخاص بك. الخط

NSMutableArray *array = [NSMutableArray array];

في الواقع لا يعطيك كائنًا محتفظًا بل كائنًا في autorelease. من المحتمل أن يتم الاحتفاظ بها في السطر التالي ، ولكن يجب عدم الإفصاح عنها في السطر الثالث. شاهد this

هذه هي القاعدة الأساسية:

يمكنك الحصول على ملكية كائن إذا قمت بإنشائه باستخدام طريقة يبدأ اسمها بـ "تخصيص" أو "جديد" أو يحتوي على "نسخ" (على سبيل المثال ، تخصيص ، newObject ، أو mutableCopy) ، أو إذا قمت بإرسال رسالة الاحتفاظ بها. أنت مسؤول عن التنازل عن ملكية الأشياء التي تملكها باستخدام الإصدار أو autorelease. في أي وقت تستلم فيه شيئًا ، يجب ألا تطلقه.


قبل تمكين الزومبي أوصي أولا بالتخلص من جميع التحذيرات (إذا كان لديك أي). يمكن أن تسبب أشياء بسيطة مثل وظيفة غير خالية بدون return هذا الخطأ. إذا لم تكن لديك تحذيرات ، فستقترح الإجابات الأخرى.


Xcode / EXC_BAD_ACCESS يكسر دائمًا في EXC_BAD_ACCESS ، تحتاج فقط إلى العمل في طريقك لأعلى مكدس الاستدعاءات للعثور على التعليمات البرمجية التي تم تشغيلها.

لاحظ أن هذه الأنواع من الأخطاء غالبًا ما تحدث مع كائنات autoreleased ، وهذا يعني أن السبب النهائي للمشكلة لن يكون في مكدس الاستدعاءات الذي تسبب في EXC_BAD_ACCESS . عند ذلك ، تصبح NSZombieEnabled و NSAutoreleaseFreedObjectCheckEnabled مفيدة.


آمل ألا تفوتني إجابة متطابقة ، لكنني وجدت أنه من الممكن لبعض المشاريع إلقاء هذا الخطأ بسبب التشغيل على أجهزة المحاكاة لإصدارات iOS القديمة التي قد لا تتوافق مع تبعية المشروع أو إطار العمل. كنت أطارد أحد هذه الأمور لفترة طويلة قبل أن أدرك أنها كانت تحدث فقط في إصدارات جهاز محاكاة الكمبيوتر ، مثل iPhone 4S ، لم يكن من المفترض أن يحاول التطبيق دعمه.

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


يتم تعيين أسلوب مفيد آخر تعيين نقاط التوقف التي سيتم تشغيل مباشرة بعد حدوث الاستثناء:

افتح نافذة نقاط التوقف (Run - Show - Breakpoints) وأضف نقطتي تعليق رمزيتين تدعى "objc_exception_throw" و "[NSException raise]"

من: http://blog.emmerinc.be/index.php/2009/03/19/break-on-exception-in-xcode/


من فئات Stanford CS193P: إذا قمت بإضافة نقطة توقف (يدويًا ، بتحرير نقاط التوقف) للحصول على الرمز objc_exception_throw يمكنك الحصول على صورة أفضل بكثير عن الخطأ - السماح للأمور objc_exception_throw إلى النقطة التي يتوقف فيها مصحح الأخطاء بحد ذاته ليحيط أشياء غامضة وشدّ أثر المكدس. عند التوقف في objc_exception_throw ، يمكنك غالبًا الرجوع إلى ما تسبب في الوصول إلى / المشكلة تمامًا.


المنجم هو .bzrignore ، ولكن نفس الفكرة :)

.DS_Store
*.mode1v3
*.pbxuser
*.perspectivev3
*.tm_build_errors

هو tm_build_errors عند استخدام TextMate لإنشاء المشروع الخاص بي. لم تكن شاملة تمامًا مثل Hagelin لكنني اعتقدت أن الأمر يستحق النشر في سطر tm_build_errors.







iphone objective-c xcode debugging exc-bad-access