سؤال

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

NSString * intValue = [ NSString stringWithFormat:@"int = %i", [ [ self.selectedObject valueForKey:name ] integerValue ] ];

selectedObject هو NSObject, ، و name يحدث أن يكون اسم أ @property من النوع int.

ما يحيرني هو السبب في أن المترجم مستعد تمامًا لافتراض أن نتيجة العودة [ self.selectedObject valueForKey:name ] من النوع NSNumber * (بدون تكوينه) من أجل ربط الرسالة باستخدام مكالمة إلى integerValue.

من الواضح أن KVC يختتم أنواع "الأرقام" غير الكائن NSNumber, ، ولكن لا توجد وسيلة حتى يعرف المترجم ذلك -valueForKey: سيعود NSNumber * في هذه الحالة بالذات.

لماذا لا يؤدي هذا إلى تحذير مترجم على غرار ""id قد لا ترد على '-integerValue'"?

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

المحلول

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

وبهذه الطريقة ، يمكنك اختيار المكان الذي تريد استخدامه في الكتابة الثابتة ، وأين تريد استخدام الكتابة الديناميكية. من القانوني تمامًا أن تفعل شيئًا كهذا:

id str1 = @"Hello";
id str2 = [str1 stringByAppendingString:@", world"];

ولكن عادة تكتب الأوتار "بإحكام" NSStringS ، لأنك تحصل على راحة فحص النوع الثابت في وقت الترجمة ، واللجوء فقط إلى الكتابة الديناميكية حيث يمكن أن يعترض الساكنة ، كما في valueForKey قارة.

نصائح أخرى

تم تمرير الوقت ولدينا أفضل للاستدلال الآن بفضل __auto_type متوفر منذ Xcode 8. لذا يمكنك الآن القيام بذلك

#define let __auto_type const
#define var __auto_type

let a = @[@"pew pew"];
var b = 2;
b = a; //compiler warning "Incompatible pointer to integer conversion assigning to 'int' from 'NSArray *__strong const'"

و أكثر بكثير

في الواقع ، لقد أحببت هذا كثيرًا ، لذا قمت بذلك كجنة للراحة.

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