محاولة فهم الكتل على iOS
-
26-09-2019 - |
سؤال
أحاول فهم كيفية استخدام الكتل على iOS. لقد قرأت مستندات Apple ، لكن كالعادة ، فهي غامضة وغير مكتملة ولم يتم ذكر عدة أجزاء أساسية من المعلومات. لدي أيضا غوغل حولها دون نجاح. هذا ما أحاول القيام به كتمرين لفهم ذلك.
لقد قمت بإنشاء كتلة لقراءة سلسلة ومقارنة السلسلة مع القراءة السابقة. إذا لم تكن الأوتار هي نفسها ، فأعود نعم ، إذا كانت متشابهة ، فالتراجع عنهم.
هكذا فعلت:
أعلنت هذا على .H
BOOL (^differentStrings)(void);
لقد أعلنت هذا على .m ، داخل ViewDidload في ViewController
__block NSString * previousString;
__block NSString * currentString;
differentStrings = ^(void){
currentString = [self getString];
NSLog(@"%@", currentString); // not printing anything on console
if (![currentString isEqualToString:previousString]) {
previousString = currentString;
return YES;
} else {
return NO;
}
};
هذه هي الطريقة التي أستخدم بها: لدي موضوع يقوم بذلك:
if (differentStrings)
NSLog (@"strings are different);
هذه هي المشاكل التي لدي:
- تُرجع الكتلة دائمًا بنعم (سلاسل مختلفة)
- أنا لست مرتاحًا لإعلان هذا داخل حمولة VidedIdload. كيف يجب أن أعلن ذلك ، حتى أتمكن من استخدامه على مستوى العالم كطريقة؟ هل يجب أن أضع هذا كما أود مع طريقة؟
- أنا أسمي طريقة "getstring" داخل الكتلة. هل الامور على ما يرام؟
- أجد غريبًا أن أعلن متغيرات الكتلة على .m. كما أرى ، يجب أن أعلن أن متغيرات الكتلة في .H ثم استخدمها فقط على .m. لقد حاولت القيام بذلك ، لكنني تلقيت خطأ.
- لقد قمت بإعداد نقطة تصحيح الأخطاء على السطر الأول من الكتلة ولكنها لا تتوقف هناك ؛
- خط NSLOG داخل الكتلة لا يطبع أي شيء. أليست الكتلة التي يتم استدعاؤها؟
هل يمكنك أن تساعدني يا رفاق في هذا؟
المحلول
أنت سوء فهم كيفية عمل الكتل. (حسنًا ، هذا واضح نوعًا ما.) بنفس الطريقة previousString
هو متغير يشير إلى NSString ، differentStrings
هو متغير يشير إلى أ الكتلة. ليس نتيجة تشغيل الكتلة ، بل الكتلة نفسها. هذا هو ، بعد القيام بذلك:
__block NSString * previousString;
__block NSString * currentString;
differentStrings = ^(void){
currentString = [self getString];
NSLog(@"%@", currentString); // not printing anything on console
if (![currentString isEqualToString:previousString]) {
previousString = currentString;
return YES;
} else {
return NO;
}
};
differentStrings
هو متغير يشير إلى الكتلة. ثم عندما تفعل هذا:
if (differentStrings)
... أنت ببساطة تتحقق مما إذا كان differentStrings
يحتوي على شيء آخر غير 0 أو NULL. نظرًا لأنه يحتوي على كتلة ، فهي ليست فارغة ، لذلك فهي تُقيّم إلى True.
تذكر: differentStrings
هو متغير كتلة ، وليس متغير المنحة. يحتوي على كتلة (وظيفة ، إن شئت) ، عندما تكون عندما اتصل سيعود منطقي. وبالتالي ، من أجل تشغيل الكتلة بالفعل ، تحتاج إلى تسميتها. مثله:
differentStrings();
أو في قضيتك:
if (differentStrings()) {
NSLog (@"strings are different");
}
يحرر: كما أشار في التعليقات ، منذ ذلك الحين differentStrings
هو متغير مثيل ، تحتاج إلى ذلك copy
انها ، تماما كما تتصل retain
على أي كائن آخر تم تعيينه إلى متغير مثيل. (لأسباب تقنية لن أذهب إليها الآن ، يجب عليك دائمًا استخدامها copy
مع كتل بدلا من retain
.) وبالمثل ، ستحتاج إلى الاتصال release
عليها في وقت لاحق ، ربما في الخاص بك dealloc
طريقة.
نصائح أخرى
لا أعتقد أنك تنفذ الكتلة بالفعل. أعتقد أن رمزك يجب أن يكون
if (differentStrings())
{
NSLog (@"strings are different);
}
علاج كتلة مثل وظيفة. أعتقد أنك كنت تتحقق فقط لمعرفة ما إذا كانت الكتلة قد تم تعريفها ، وليس تنفيذها.
أيضًا ، إذا لم تكن بحاجة إلى الوصول إلى NSString خارج الكتلة ، فيمكنك التخلص من __block
التصفيات وحرك currentString
إعلان داخل الكتلة.
إذا كنت بحاجة إلى مورد آخر على الكتل ، فأنا أغطيها في جلسة الخريف في دورة تطوير iOS المتقدمة على iTunes u. أصف بناء جملة الكتلة في فهم جلسة الكاكاو ، واستخدامها في Grand Central Dispatch ضمن جلسة الرئاسة المتعددة. تحتوي ملاحظات الدورة أيضًا على روابط لبعض تطبيقات العينة التي تستخدم الكتل بطرق مختلفة.
لا يمكنني أيضًا التوصية بدرجة كافية أن تشاهد WWDC 2010 جلسات الفيديو 206 - تقديم الكتل و Grand Central Dispatch على iPhone و 211 - تبسيط تطوير تطبيق iPhone مع Grand Central Dispatch.