كيفية استدعاء التنفيذ الأصلي عند الكتابة فوق طريقة مع فئة؟
-
28-09-2019 - |
سؤال
أحاول معرفة كيف تعمل الأشياء حقًا. لذلك فكرت عندما كنت سأطالب طرقًا معينة باستخدام الفئات ، سأحصل على nslogs مثيرة للاهتمام.
@implementation UIView(Learning)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
NSLog(@"-hitTest:withEvent: event=%@", event);
return [self hitTest:point withEvent:event];
}
@end
سوبر ونفس لا تعمل هنا. هل هناك طريقة لاستدعاء التنفيذ الأصلي لـ -hittest: withEvent:؟ ما أريده هو nslog في كل مرة -هيست: withevent: يتم استدعاؤه على uiview.
انها فقط لأغراض التعلم الشخصي. أريد أن أرى تسليم الحدث أثناء العمل.
المحلول
يمكنك القيام بذلك ، ولكن عدم استخدام فئة. فئة تحل محل الطريقة. (تحذير ، تشبيه السيارة) إذا كان لديك سيارة ، وقمت بتدمير تلك السيارة واستبدالها بسيارة جديدة ، هل لا يزال بإمكانك استخدام السيارة القديمة؟ لا ، لأنه ذهب ولم يعد موجودًا. الشيء نفسه مع الفئات.
ما يمكنك فعله هو استخدام وقت تشغيل الهدف-C لإضافة الطريقة تحت اسم مختلف في وقت التشغيل (قل ، "bogusHitTest:withEvent:
") ، ثم تبادل تطبيقات hitTest:withEvent:
و bogusHitTest:withEvent:
. بهذه الطريقة عندما يستدعي الرمز hitTest:withEvent:
, ، سوف يقوم بتنفيذ الكود الذي تم كتابته في الأصل bogusHitTest:withEvent:
. يمكنك بعد ذلك الحصول على هذا الرمز bogusHitTest:withEvent:
, ، والتي سوف تنفذ التنفيذ الأصلي.
لذا فإن طريقة الزائفة ستبدو:
- (UIView *) bogusHitTest:(CGPoint)point withEvent:(UIEvent *)event {
NSLog(@"executing: %@", NSStringFromSelector(_cmd));
return [self bogusHitTest:point withEvent:event];
}
الرمز المتمثل في تبديل الأساليب سيكون شيئًا على غرار:
Method bogusHitTest = class_getInstanceMethod([UIView class], @selector(bogusHitTest:withEvent:));
Method hitTest = class_getInstanceMethod([UIView class], @selector(hitTest:withEvent:));
method_exchangeImplementations(bogusHitTest, hitTest);
نصائح أخرى
ما تريد القيام به يسمى الطريقة swizzling: http://www.cocoadev.com/index.pl؟methodswizzling
لسوء الحظ ، لا ، لا توجد طريقة لاستدعاء التنفيذ الأصلي لطريقة يمكنك تجاوزها. بمجرد تنفيذه في الفئة ، قمت بإلغاء الطريقة الأصلية.
إرسال نفس الرسالة إلى super
يجب أن تعمل في طريقتك ؛ سوف تسمي الطريقة على الفئة الفائقة كالمعتاد (إذا كان هناك واحد).
إرسال نفس الرسالة إلى self
سيقوم بإنشاء حلقة لا حصر لها ، كما أنا متأكد من أنك اكتشفت.