سؤال

وجئت عبر مشكلة غريبة اليوم. أنا خلقت فئة فرعية من UIView وأضاف 1 الطريقة فقط إلى رمز النموذج المقدم من كسكودي.

@interface FloatView : UIView {

}
- (void)floatTest:(CGFloat)x;
@end

- (void)floatTest:(CGFloat)x {
  NSLog(@"float was %f", x);
}

وبعد ذلك في بلدي appDelegate كان رمز مثل هذا:

UIView *floatView = [[FloatView alloc] init];
[floatView floatTest:10.0f];

وبسيطة جدا، أليس كذلك؟ ما يجب أن هذا طباعة؟ أنا اعتقد انه سيكون شيئا مثل "10.0000"، ولكن لا، فإنه يطبع خارج "0.000000".

وأنا تصارعت مع هذا لساعات، في محاولة لمعرفة ما كنت أفعله خطأ، وبعد ذلك بتغيير رمز في بلدي appDelegate إلى

FloatView *floatView = [[FloatView alloc] init];
[floatView floatTest:10.0f];

وبعد ذلك فقط، إلا أنها تطبع المتوقع "10.0000". لماذا هو كذلك؟ لقد أعلن FloatView كما فئة فرعية من UIView، لا ينبغي أن يكون كنت قادرا على تعيين كائن FloatView إلى مؤشر UIView دون مشاكل؟

وعلى الرغم من أعلن floatView مؤشر إلى UIView، انها حقا floatView ويجب أن تكون قادرة على التعامل مع الرسالة floatTest؟ أنا خارج تماما قاعدة هنا؟

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

المحلول

والواقع، تعدد الأشكال تعمل كما هو متوقع. إذا لم يعمل، لكان قد تم طبع شيء (في المثال الخاص بك، 0.0000 يتم طباعة). الشيء هو، في حين أن لديك مثيل يستجيب فعلا لtestFloat:10.0f رسالة، لأن المترجم لا يمكن أن نرى بشكل ثابت إعلان طريقة (من الطبقة UIView لا تعلن مثل هذا الأسلوب)، فإنه يفترض أن الأسلوب الخاص بك يأخذ ... كوسيطة والعودة id.

وعندما يتم تمرير CGFloat إلى الطريقة التي يتوقع عدد متغير من الوسائط (...)، يتم الترويج لها double. وهكذا، يتم تمرير طريقة الاستقبال حجة double ويعتقد انها float ولا يحصل طباعته بشكل صحيح.

ويمكنك التحقق من هذا السلوك عن طريق تغيير خط NSLog إلى:

NSLog(@"%f", *(double*)&x);

وعندما يرسل مترجم الرسالة إلى FloatView* بدلا من UIView*، فإنه يمكن العثور على توقيع الدقيق للطريقة. ويمكن أن نرى ذلك حقا تتوقع CGFloat ولا يشجع على حجة لdouble. ونتيجة لذلك، وأنها تعمل بشكل صحيح.

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

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