سؤال

أحاول فهم كيفية استخدام الكتل على 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);

هذه هي المشاكل التي لدي:

  1. تُرجع الكتلة دائمًا بنعم (سلاسل مختلفة)
  2. أنا لست مرتاحًا لإعلان هذا داخل حمولة VidedIdload. كيف يجب أن أعلن ذلك ، حتى أتمكن من استخدامه على مستوى العالم كطريقة؟ هل يجب أن أضع هذا كما أود مع طريقة؟
  3. أنا أسمي طريقة "getstring" داخل الكتلة. هل الامور على ما يرام؟
  4. أجد غريبًا أن أعلن متغيرات الكتلة على .m. كما أرى ، يجب أن أعلن أن متغيرات الكتلة في .H ثم استخدمها فقط على .m. لقد حاولت القيام بذلك ، لكنني تلقيت خطأ.
  5. لقد قمت بإعداد نقطة تصحيح الأخطاء على السطر الأول من الكتلة ولكنها لا تتوقف هناك ؛
  6. خط 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.

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