سؤال

لديّ خط رمز بسيط للغاية في الهدف-C:

if ((selectedEntity != nil) && [selectedEntity isKindOfClass:[MobileEntity class]])

من حين لآخر ولأي سبب من الأسباب ، تعطل اللعبة على هذا السطر من الكود مع الوصول إلى BAD. عادة ما يبدو الأمر يتعلق بالوقت الذي يتم فيه إزالة شيء ما من الملعب ، لذلك أعتقد أن ماذا كان المحدد يحصل على dealloc'd ، ثم هذه النتائج. بصرف النظر عن كونه مستحيل اختيار الكيانات المخرج (ولكن من يدري ، ربما هذا ليس صحيحًا بالفعل في الكود الخاص بي ...) ، حقيقة أنني أتحقق بشكل خاص لمعرفة ما إذا كان هناك هو هناك مجموعة محددة قبل الوصول إليها تعني أنه لا ينبغي أن أواجه أي مشاكل هنا. من المفترض أن يدعم الهدف-C التوصيف المنطقي القصيرة ، ولكن يبدو أنه لا يتم تحريره: يبدو أن الدائرة القصيرة لا علاقة لها بالمشكلة.

أيضًا ، وضعت @try/ @ @ @كتلة الكود هذه لأنني علمت أنها تنفجر بين الحين والآخر ، لكن يبدو أن هذا يتم تجاهله (أعتقد أنه لا يمكن القبض على وصول Bad-bad).

لذا ، فأنا أتساءل في الأساس عما إذا كان أي شخص يعرف إما طريقة يمكنني التقاطها ورميها (لأنني لا أهتم بهذا الخطأ طالما أنه لا يجعل اللعبة تعطل) أو يمكن أن تشرح سبب حدوثها . أعلم أن الهدف-C يفعل أشياء غريبة مع قيمة "NIL" ، لذلك أعتقد أنها تشير إلى بعض المساحة الغريبة التي ليست مؤشر كائن أو لا شيء.

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

تحرير: يبدو أن هناك حالة هامشية تتيح لك تحديد كيان قبل محوها. لذلك ، يبدو أن تقدم الرمز يسير على هذا النحو:

selectedEntity = obj;
NSAutoreleasePool *pool = ...;
[obj release];
if (selectedEntity != nil && etc...) {}
[pool release];

لذلك أظن أنه نظرًا لأن تجمع Autorelease لم يتم إصداره بعد ، فإن الكائن ليس شيئًا ولكن عدد الاحتفاظ به عند 0 ، لذا لا يُسمح بالوصول إليه على أي حال ... أو أي شيء على هذا المنوال؟

أيضا ، لعبتي ذات الخيوط الفردية ، لذلك هذه ليست مشكلة خيوط.

تحرير: لقد أصلحت المشكلة ، بطريقتين. أولاً ، لم أسمح باختيار الكيان في تلك الحالة الهامشية. ثانياً ، بدلاً من الاتصال فقط [الكيانات removeObjectatIndex: i] (الكود لإزالة أي كيانات سيتم حذفها) ، قمت بتغييره إلى:

//Deselect it if it has been selected.
if (entity == selectedEntity)
{
    selectedEntity = nil;
}

[entities removeObjectAtIndex:i];

فقط تأكد من قيامك بتعيين NIL للمتغير في نفس الوقت الذي تحرره منه ، كما اقترح JIB.

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

المحلول

إذا تم إصدار كائن (محدد) و dealloc'd هو ليس == nil. إنه مؤشر لقطعة تعسفية من الذاكرة ، ويؤجلها (إذا (محدد! = nil) هو خطأ في البرمجة (exc_bad_access).

ومن ثم نموذج OBJ-C الشائع:-

إصدار محدد] ؛ محدد = لا شيء ؛

نصائح أخرى

هذا لا علاقة له بالدورة القصيرة. الهدف-C يأكل الرسائل إلى لا شيء selectedEntity != nil ليس ضروريًا (نظرًا لأن الرسائل التي لا تُعود إلى أنواع إرجاع Bool).

exc_bad_access ليس استثناءًا قابلًا للتطبيق. إنه فشل كارثي بشكل عام ناتج عن محاولة متابعة مؤشر غير صالح.

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

قم بتشغيل nszombies وحاول مرة أخرى.

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


تم تحرير منشورك للإشارة إلى أن الإصلاح هو:

//Deselect it if it has been selected.
if (entity == selectedEntity)
{
    selectedEntity = nil;
}

[entities removeObjectAtIndex:i];

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

لقد قرأت هذا للتو http://developer.apple.com/mac/library/qa/qa2004/qa1367.html الأمر الذي أشار إلى أن الخطأ الذي تحصل عليه هو نتيجة لإفراط في إطلاق الكائن. هذا يعني أن altoughentity selectity هو nill ، لقد أصدرته عدة مرات ، ولم يعد لديك لاستخدامك بعد الآن ..

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

هل ربما تفعل شيئًا داخل الكتلة التي يمكن أن تسبب الاستثناء؟

 

selectedEntity = obj;
NSAutoreleasePool *pool = ...;
[obj release];
if (selectedEntity != nil && etc...) {}
[pool release];

 

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

أردت أن تتمثل في تعويض OBJ بدلاً من إطلاقه.

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