تم إرجاع استخدام Ivar في Block إلى كائن آخر
-
01-10-2019 - |
سؤال
لقد وجدت تصادمًا في تطبيق iPhone مع Target iOS 4 يتغير اعتمادًا على نوع الإنشاء.
لم يمنحني مصحح الأخطاء الكثير
UIViewController *result = [self factory](self);
مع exc_bad_access. self
هو فئة وراثة من NSObject (كما هو موضح أدناه باسم nsobjectinheritor). يتم تمكين الزومبي. لقد حاولت تغيير الطريقة factory
ثلاث طرق مع النتائج التالية.
هذا يعطل في كل من التصحيح والبناء المخصص ...
- (FactoryMethod) factory;
{
return [^ UIViewController * (NSObjectInheritor *newThing)
{
return [[ViewControllerClass alloc] initWithStuff:(boolValue ? foo : bar)];
} autorelease];
}
هذا يعمل في تصحيح التصحيح ولكنه يعطل في مخصص ...
- (FactoryMethod) factory;
{
return [^ UIViewController * (NSObjectInheritor *newThing)
{
if(boolValue)
{
return [[ViewControllerClass alloc] initWithStuff:foo];
}
else
{
return [[ViewControllerClass alloc] initWithStuff:bar];
}
} autorelease];
}
هذا يعمل في كل من Debug و Ad Hoc ولكنه قبيح للغاية ومتكرر:
- (FactoryMethod) factory;
{
if(boolValue)
{
return [^ UIViewController * (NSObjectInheritor *newThing)
{
return [[ViewControllerClass alloc] initWithStuff:foo];
} autorelease];
}
else
{
return [^ UIViewController * (NSObjectInheritor *newThing)
{
return [[[ViewControllerClass alloc] initWithStuff:bar];
} autorelease];
}
}
نظريتي هي ذلك boolValue
لا يمكن الوصول إليها في الوقت الذي يتم فيه تنفيذ الكتلة التي تم إرجاعها. إنها
@interface SubclassOfNSObjectInheritor : NSObjectInheritor
{
BOOL boolValue;
}
@property (readonly) BOOL boolValue;
(YES
أو NO
تم تعيينه في init فئة فرعية
@synthesize boolValue;
في تنفيذ الفئة الفرعية.
الأسئلة النهائية هي - هل نظريتي حول ما هو الخطأ الصحيح؟ هل الطريقة الثالثة للقيام بذلك - التي تم الإشارة إليها على أنها تعمل في بنية AD HOC وتصحيح الأخطاء - آمنة؟ ما هي أفضل طريقة للقيام بذلك؟
المحلول
مشكلتك مضاعفة ، أولاً ، تقوم بإفراط في المبالغة في الكتلة والثانية ، يتم إنشاء الكتل على المكدس ، والتي تختفي عند إرجاع طريقتك (تقوم بشكل أساسي بإرجاع مؤشر إلى إطار المكدس المدمر سابقًا).
بدلاً من ذلك ، انسخ الكتلة وإصدارها التلقائي قبل العودة. يمكنك القيام بذلك بطريقة Objective-C مع أ copy
الرسالة ، يمكنك الاتصال بـ Block_copy()
وظيفة.
تحطمك في التكوينات المختلفة هو حدث pure. لذلك ، لإصلاح أحد تطبيقاتك:
- (FactoryMethod) factory;
{
return [[^(NSObjectInheritor *newThing)
{
if(boolValue)
{
return [[ViewControllerClass alloc] initWithStuff:foo];
}
else
{
return [[ViewControllerClass alloc] initWithStuff:bar];
}
} copy] autorelease];
}