ما هي أفضل الممارسات التي تستخدمها عند كتابة Objective-C وCocoa؟[مغلق]

StackOverflow https://stackoverflow.com/questions/155964

سؤال

أنا أعرف عن عالية (وهو أمر مفيد جدًا!) ولكن ما هي ممارسات البرمجة التي تستخدمها عند كتابة Objective-C، وبشكل أكثر تحديدًا عند استخدام Cocoa (أو CocoaTouch).

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

المحلول

هناك بعض الأشياء التي بدأت في القيام بها والتي لا أعتقد أنها قياسية:

1) مع ظهور الخصائص، لم أعد أستخدم "_" لبادئة متغيرات الفئة "الخاصة".بعد كل شيء، إذا كان من الممكن الوصول إلى المتغير بواسطة فئات أخرى، ألا ينبغي أن تكون هناك خاصية له؟لم تعجبني دائمًا البادئة "_" لأنها تجعل التعليمات البرمجية قبيحة، والآن يمكنني استبعادها.

2) عند الحديث عن الأشياء الخاصة، أفضّل وضع تعريفات الأساليب الخاصة داخل الملف .m في ملحق الفصل كما يلي:

#import "MyClass.h"

@interface MyClass ()
- (void) someMethod;
- (void) someOtherMethod;
@end

@implementation MyClass

لماذا تشوش ملف .h بأشياء لا ينبغي أن يهتم بها الغرباء؟يعمل () الفارغ مع الفئات الخاصة في ملف .m، ويصدر تحذيرات تجميعية إذا لم تقم بتنفيذ الطرق المعلنة.

3) لقد اتخذت وضع Dealloc في الجزء العلوي من الملف .m، أسفل توجيهات @synthesize مباشرةً.ألا ينبغي أن يكون ما قمت بتخصيصه في أعلى قائمة الأشياء التي تريد التفكير فيها في الفصل الدراسي؟وهذا صحيح بشكل خاص في بيئة مثل iPhone.

3.5) في خلايا الجدول، اجعل كل عنصر (بما في ذلك الخلية نفسها) معتمًا للأداء.وهذا يعني تحديد لون الخلفية المناسب في كل شيء.

3.6) عند استخدام NSURLConnection، كقاعدة قد ترغب في تنفيذ طريقة التفويض:

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
                  willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
      return nil;
}

أجد أن معظم مكالمات الويب فردية للغاية وهي استثناء أكثر من كونها قاعدة، حيث سترغب في تخزين الردود مؤقتًا، خاصة لمكالمات خدمة الويب.يؤدي تنفيذ الطريقة كما هو موضح إلى تعطيل التخزين المؤقت للاستجابات.

ومن المثير للاهتمام أيضًا بعض النصائح الجيدة الخاصة بـ iPhone من Joseph Mattiello (المستلمة في القائمة البريدية لـ iPhone).هناك المزيد، ولكن هذه كانت الأكثر فائدة على ما أعتقد (لاحظ أنه تم الآن تعديل بعض الأجزاء قليلاً من النص الأصلي لتشمل التفاصيل المقدمة في الردود):

4) استخدم الدقة المزدوجة فقط إذا كان عليك ذلك، كما هو الحال عند العمل مع CoreLocation.تأكد من إنهاء الثوابت الخاصة بك بـ "f" لجعل دول مجلس التعاون الخليجي تخزنها كعوامات.

float val = someFloat * 2.2f;

هذا مهم في الغالب عندما someFloat قد يكون في الواقع مزدوجًا، فأنت لا تحتاج إلى حسابات الوضع المختلط، نظرًا لأنك تفقد الدقة في "val" عند التخزين.على الرغم من أن أرقام الفاصلة العائمة مدعومة في أجهزة iPhone، إلا أن الأمر قد يستغرق وقتًا أطول لإجراء عمليات حسابية مزدوجة الدقة بدلاً من الدقة الفردية.مراجع:

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

5) قم بتعيين خصائصك كـ nonatomic.هم atomic بشكل افتراضي، وبعد التوليف، سيتم إنشاء رمز الإشارة لمنع مشاكل الخيوط المتعددة.ربما لا يحتاج 99% منكم إلى القلق بشأن هذا الأمر، كما أن الكود يكون أقل تضخمًا وأكثر كفاءة في الذاكرة عند ضبطه على غير ذري.

6) يمكن أن تكون SQLite طريقة سريعة جدًا لتخزين مجموعات كبيرة من البيانات مؤقتًا.على سبيل المثال، يمكن لتطبيق الخريطة تخزين مربعاته في ملفات SQLite.أغلى جزء هو القرص I/O.تجنب العديد من عمليات الكتابة الصغيرة عن طريق الإرسال BEGIN; و COMMIT; بين الكتل الكبيرة.نحن نستخدم مؤقتًا مدته ثانيتان على سبيل المثال يتم إعادة تعيينه عند كل إرسال جديد.عند انتهاء صلاحيتها، نرسل COMMIT؛، مما يجعل كل كتاباتك تذهب في قطعة واحدة كبيرة.يقوم SQLite بتخزين بيانات المعاملات على القرص، ويؤدي القيام بالتفاف البدء/النهاية هذا إلى تجنب إنشاء العديد من ملفات المعاملات، وتجميع كافة المعاملات في ملف واحد.

بالإضافة إلى ذلك، سيقوم SQL بحظر واجهة المستخدم الرسومية الخاصة بك إذا كانت موجودة في مؤشر الترابط الرئيسي الخاص بك.إذا كان لديك استعلام طويل جدًا، فمن الجيد تخزين استعلاماتك ككائنات ثابتة، وتشغيل SQL الخاص بك في سلسلة رسائل منفصلة.تأكد من التفاف أي شيء يعدل قاعدة البيانات لسلاسل الاستعلام فيه @synchronize() {} كتل.بالنسبة للاستعلامات القصيرة، ما عليك سوى ترك الأشياء في الموضوع الرئيسي لتسهيل الأمر.

يوجد المزيد من النصائح حول تحسين SQLite هنا، على الرغم من أن المستند يبدو قديمًا، إلا أن العديد من النقاط ربما لا تزال جيدة؛

http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html

نصائح أخرى

لا تستخدم سلاسل مجهولة كسلاسل شكل

عند أساليب أو وظائف تأخذ حجة شكل سلسلة، يجب عليك التأكد من أن لديك السيطرة على المحتوى من سلسلة التنسيق.

وعلى سبيل المثال، عند تسجيل الجمل، وأنه من المغري لتمرير متغير سلسلة كوسيطة الوحيدة لNSLog:

    NSString *aString = // get a string from somewhere;
    NSLog(aString);

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

    NSLog(@"%@", aString);

استخدم اصطلاحات ومصطلحات تسمية وتنسيق Cocoa القياسية بدلاً من أي شيء اعتدت عليه من بيئة أخرى.هناك نكون هناك الكثير من مطوري Cocoa، وعندما يبدأ واحد منهم آخر في العمل مع التعليمات البرمجية الخاصة بك، سيكون الأمر أكثر سهولة إذا كان يبدو مشابهًا لرموز Cocoa الأخرى.

أمثلة على ما يجب فعله وما لا يجب فعله:

  • لا تعلن id m_something; في واجهة الكائن ونسميها a متغير العضو أو مجال;يستخدم something أو _something لاسمها ونسميها المتغيرات الخاصة.
  • لا اسم getter -getSomething;اسم الكاكاو الصحيح هو فقط -something.
  • لا اسم واضعة -something:;ينبغي أن يكون -setSomething:
  • يتخلل اسم الطريقة الوسائط ويتضمن النقطتين؛إنه -[NSObject performSelector:withObject:], ، لا NSObject::performSelector.
  • استخدم الحروف الكبيرة (CamelCase) في أسماء الطرق والمعلمات والمتغيرات وأسماء الفئات وما إلى ذلك.بدلاً من الخطوط السفلية (الشرطات السفلية).
  • تبدأ أسماء الفئات بحرف كبير، وأسماء المتغيرات وأسماء الطرق بأحرف صغيرة.

أيًا كان ما تفعله، لا استخدم التدوين المجري بنمط Win16/Win32.حتى Microsoft تخلت عن ذلك بالانتقال إلى النظام الأساسي .NET.

IBOutlets

وتاريخيا، كان إدارة الذاكرة من وسائل الفقراء. أفضل الممارسات الحالية هي أن يعلن منافذ من الخصائص:

@interface MyClass :NSObject {
    NSTextField *textField;
}
@property (nonatomic, retain) IBOutlet NSTextField *textField;
@end
<ع> استخدام خصائص يجعل دلالات إدارة الذاكرة واضحة. كما يوفر نمط ثابت إذا كنت تستخدم المثال تركيب متغير.

استخدم محلل LLVM/Clang الثابت

ملحوظة:ضمن Xcode 4 تم دمج هذا الآن في IDE.

أنت تستخدم Clang محلل ثابت لتحليل - بشكل غير مفاجئ - كود C وObjective-C (لا يوجد C++ بعد) على نظام التشغيل Mac OS X 10.5.من السهل التثبيت والاستخدام:

  1. تحميل الإصدار الأخير من هذه الصفحة.
  2. من سطر الأوامر، cd إلى دليل المشروع الخاص بك.
  3. ينفذ scan-build -k -V xcodebuild.

(هناك بعض القيود الإضافية وما إلى ذلك، على وجه الخصوص، يجب عليك تحليل المشروع في تكوين "التصحيح" الخاص به - راجع http://clang.llvm.org/StaticAnapsyUsage.html للحصول على تفاصيل - ولكن هذا هو ما يتلخص في الأمر بشكل أو بآخر.)

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

وهذا هو دهاء واحد ولكن في متناول يدي واحد. إذا كنت تمر نفسك كمندوبة إلى كائن آخر، إعادة تعيين مندوب لهذا الكائن قبل أن dealloc.

- (void)dealloc
{
self.someObject.delegate = NULL;
self.someObject = NULL;
//
[super dealloc];
}

ووبذلك كنت التأكد من أن أية أساليب مندوب المزيد من سوف تحصل على إرسالها. كما كنت على وشك أن dealloc وتختفي في الأثير كنت ترغب في التأكد من أن لا شيء يمكن أن نرسل لك أي رسائل أخرى عن طريق الصدفة. أتذكر self.someObject يمكن أن تحتفظ بها كائن آخر (يمكن أن يكون مفرد أو على بركة autorelease أو أيا كان) وحتى اقول لكم انها "التوقف عن إرسال رسائل لي!"، فإنه يعتقد الكائن للتو عن ليكون-dealloced الخاص بك هي لعبة عادلة.

والدخول في هذه العادة سوف يخلصك من الكثير من الحوادث الغريبة التي هي الألم التصحيح.

ونفس مبدأ ينطبق على مراقبة القيمة الأساسية، وNSNotifications جدا.

وتحرير:

وحتى أكثر دفاعية، تغيير:

self.someObject.delegate = NULL;

في:

if (self.someObject.delegate == self)
    self.someObject.delegate = NULL;

وkendell

وبدلا من:

@interface MyClass (private)
- (void) someMethod
- (void) someOtherMethod
@end

استخدم:

@interface MyClass ()
- (void) someMethod
- (void) someOtherMethod
@end

والجديد في الهدف-C 2.0.

موصوفة

وملحقات فئة في الهدف-C 2.0 المرجعي لشركة أبل.

"ملحقات الدرجة تسمح لك ليعلن API المطلوب إضافية لفئة في أماكن أخرى من داخل كتلةinterface الطبقة الأولية"

وحتى انهم جزء من الطبقة الفعلية - وليس (خاصة) الفئة بالإضافة إلى الفئة. الدقيقة ولكنها مهمة الفرق.

تجنب التحرير التلقائي

نظرًا لأنك عادةً(1) لا تملك تحكمًا مباشرًا في عمرها الافتراضي، يمكن أن تستمر الكائنات التي تم إصدارها تلقائيًا لفترة طويلة نسبيًا وتزيد بشكل غير ضروري من مساحة ذاكرة التطبيق الخاص بك.على الرغم من أن هذا قد لا يكون له أي نتيجة تذكر على سطح المكتب، إلا أنه قد يمثل مشكلة كبيرة على الأنظمة الأساسية الأكثر تقييدًا.لذلك، في جميع الأنظمة الأساسية، وخاصة الأنظمة الأساسية الأكثر تقييدًا، يعتبر من أفضل الممارسات تجنب استخدام الأساليب التي قد تؤدي إلى كائنات تم إصدارها تلقائيًا وبدلاً من ذلك يتم تشجيعك على استخدام نمط التخصيص/التهيئة.

وهكذا، بدلاً من:

aVariable = [AClass convenienceMethod];

حيثما أمكن، يجب عليك بدلاً من ذلك استخدام:

aVariable = [[AClass alloc] init];
// do things with aVariable
[aVariable release];

عندما تكتب أساليبك الخاصة التي تُرجع كائنًا تم إنشاؤه حديثًا، يمكنك الاستفادة من ذلك اصطلاح تسمية الكاكاو لإعلام المتلقي بأنه يجب تحريره عن طريق إضافة اسم الطريقة بكلمة "جديد" مسبقًا.

وهكذا بدلاً من:

- (MyClass *)convenienceMethod {
    MyClass *instance = [[[self alloc] init] autorelease];
    // configure instance
    return instance;
}

يمكنك الكتابة:

- (MyClass *)newInstance {
    MyClass *instance = [[self alloc] init];
    // configure instance
    return instance;
}

نظرًا لأن اسم الطريقة يبدأ بـ "جديد"، فإن مستهلكي واجهة برمجة التطبيقات (API) الخاصة بك يعرفون أنهم مسؤولون عن تحرير الكائن المستلم (انظر، على سبيل المثال، NSObjectController newObject طريقة).

(1) يمكنك التحكم باستخدام مجموعات الإصدار التلقائي المحلية الخاصة بك.للمزيد عن هذا، راجع تجمعات الإصدار التلقائي.

لقد تم ذكر بعض هذه الأشياء بالفعل، ولكن إليك ما يمكنني التفكير فيه من أعلى رأسي:

  • اتبع قواعد تسمية KVO. حتى لو كنت لا تستخدم KVO الآن، فمن خلال تجربتي في كثير من الأحيان فإنه لا يزال مفيدًا في المستقبل.وإذا كنت تستخدم KVO أو الروابط، فأنت بحاجة إلى معرفة أن الأمور تسير بالطريقة التي من المفترض أن تعمل بها.لا يغطي هذا طرق الوصول ومتغيرات الحالة فحسب، بل يشمل أيضًا العلاقات المتعددة والتحقق من الصحة والمفاتيح التابعة للإخطار التلقائي وما إلى ذلك.
  • ضع الأساليب الخاصة في فئة. ليس فقط الواجهة، ولكن التنفيذ أيضًا.من الجيد أن تكون هناك مسافة من الناحية المفاهيمية بين الأساليب الخاصة وغير الخاصة.أقوم بتضمين كل شيء في ملف .m الخاص بي.
  • ضع أساليب موضوع الخلفية في فئة. نفس ما ورد أعلاه.لقد وجدت أنه من الجيد الاحتفاظ بحاجز مفاهيمي واضح عندما تفكر في ما هو موجود في الموضوع الرئيسي وما هو غير موجود.
  • يستخدم #pragma mark [section]. عادةً ما أقوم بالتجميع حسب طرقي الخاصة، وتجاوزات كل فئة فرعية، وأي معلومات أو بروتوكولات رسمية.وهذا يجعل من السهل جدًا الانتقال إلى ما أبحث عنه بالضبط.في نفس الموضوع، قم بتجميع الأساليب المتشابهة (مثل طرق تفويض طريقة عرض الجدول) معًا، ولا تضعها في أي مكان.
  • بادئة الطرق الخاصة و ivars بـ _. تعجبني الطريقة التي يبدو بها، ومن غير المرجح أن أستخدم ivar عندما أقصد عقارًا عن طريق الصدفة.
  • لا تستخدم أساليب/خصائص mutator في init & Dealloc. لم يحدث لي أي شيء سيء بسبب ذلك، ولكن يمكنني رؤية المنطق إذا قمت بتغيير الطريقة للقيام بشيء يعتمد على حالة الكائن الخاص بك.
  • ضع IBOutlets في الخصائص. لقد قرأت هذا للتو هنا، لكنني سأبدأ في القيام بذلك.بغض النظر عن أي فوائد للذاكرة، يبدو الأمر أفضل من الناحية الأسلوبية (على الأقل بالنسبة لي).
  • تجنب كتابة التعليمات البرمجية التي لا تحتاج إليها مطلقًا. يغطي هذا حقًا الكثير من الأشياء، مثل صنع ivars عندما يكون a #define سيفعل ذلك، أو تخزين مصفوفة مؤقتًا بدلاً من فرزها في كل مرة تكون فيها البيانات مطلوبة.هناك الكثير مما يمكنني قوله حول هذا الأمر، ولكن خلاصة القول هي عدم كتابة التعليمات البرمجية حتى تحتاج إليها، أو يخبرك محلل التعريف بذلك.إنه يجعل الحفاظ على الأشياء أسهل بكثير على المدى الطويل.
  • أكمل ما بدأته. يعد وجود الكثير من التعليمات البرمجية التي تجرها الدواب غير مكتملة هو أسرع طريقة لقتل المشروع.إذا كنت بحاجة إلى طريقة جيدة، فما عليك سوى الإشارة إليها عن طريق الوضع NSLog( @"stub" ) في الداخل، أو كيفما تريد لتتبع الأشياء.

كتابة اختبارات الوحدةيمكنك اختبار أ كثير من الأشياء في الكاكاو التي قد تكون أصعب في أطر أخرى.على سبيل المثال، باستخدام رمز واجهة المستخدم، يمكنك بشكل عام التحقق من أن الأشياء متصلة كما ينبغي والثقة في أنها ستعمل عند استخدامها.ويمكنك إعداد أساليب الحالة واستدعاء المفوض بسهولة لاختبارها.

ليس لديك أيضًا جمهور مقابل.المحمية مقابلإن رؤية الطريقة الخاصة تعيق كتابة الاختبارات لأعضاءك الداخليين.

والقاعدة الذهبية: إذا كنت alloc فإنك release

وUPDATE: إلا إذا كنت تستخدم ARC

لا تكتب الهدف-C كما لو كان جافا / C # / C ++ / الخ.

ورأيت مرة واحدة في فريق تستخدم لكتابة تطبيقات الويب جافا EE محاولة لكتابة تطبيق الكاكاو سطح المكتب. كما لو كان تطبيق ويب جافا EE. كان هناك الكثير من AbstractFooFactory وFooFactory وIFoo وفو تحلق حولها عند كل ما يحتاجونه حقا وفئة فو وربما بروتوكول Fooable.

وجزء من ضمان كنت لا تفعل هذا فهم حقا الاختلافات في اللغة. على سبيل المثال، لا تحتاج المصنع ومصنع فئات مجردة أعلاه لأن ترسل أساليب الفئة الهدف-C تماما كما حيوي وسائل المثال، ويمكن تجاوز في الفئات الفرعية.

تأكد من وضع إشارة مرجعية على الصفحة تصحيح ماجيك . هذا ينبغي أن يكون المحطة الأولى عند ضجيجا رأسك بالحائط بينما كان يحاول العثور على مصدر الخلل الكاكاو.

وعلى سبيل المثال، وسوف اقول لكم كيفية العثور على طريقة حيث لأول مرة تخصيص الذاكرة في وقت لاحق يسبب حوادث (مثل أثناء إنهاء التطبيق).

سلاسل

ترتيب كمستخدم تريد

عند فرز السلاسل إلى تقديم للمستخدم، لا يجب استخدام طريقة compare: بسيط. بدلا من ذلك، يجب عليك دائما استخدام أساليب المقارنة محلية مثل localizedCompare: أو localizedCaseInsensitiveCompare:.

لمزيد من التفاصيل، انظر البحث، مقارنة، والفرز سلاسل .

وفي محاولة لتجنب ما قررت الآن لاستدعاء Newbiecategoryaholism. عندما القادمين الجدد إلى الهدف-C اكتشاف الفئات التي غالبا ما تذهب الخنازير البرية، إضافة فئات صغيرة مفيدة لكل فئة في وجود (<م> "ماذا؟ يمكنني أن أضيف طريقة لتحويل رقم إلى الأرقام الرومانية إلى NSNumber على صخرة!" ).

لا تفعل هذا.

سوف

والتعليمات البرمجية الخاصة بك أن تكون أكثر المحمولة وأسهل للفهم مع العشرات من أساليب فئة قليلة رشها على أعلى فئتين عشرات الأساس.

ومعظم الوقت عندما كنت تعتقد حقا كنت في حاجة الى طريقة فئة للمساعدة في تبسيط بعض التعليمات البرمجية ستجد أنك لن ينتهي إعادة استخدام هذه الطريقة.

وهناك مخاطر أخرى أيضا، إلا إذا كنت مساحة الاسم أساليب الفئة الخاصة بك (والذي إلى جانب ddribin مجنون تماما هو؟) وهناك فرصة أن أبل، أو المساعد، أو أي شيء آخر يعمل في الفضاء عنوانك وسوف تحدد أيضا نفس الأسلوب فئة بنفس الاسم مع الآثار الجانبية مختلف قليلا ....

وOK. والآن بعد أن كنت قد حذر من تجاهل "لا تفعل هذا الجزء". ولكن ممارسة اقصى درجات ضبط النفس.

ومقاومة شاء subclasses ترث العالم. في الكاكاو ويتم الكثير من خلال وفد واستخدام وقت التشغيل الأساسية التي تتم في أطر أخرى من خلال شاء subclasses ترث.

وعلى سبيل المثال، في جاوة استخدام حالات *Listener مجهول فرعية كثيرا وفي. NET استخدام EventArgs بك فرعية الكثير. في الكاكاو، لم تقم أي - يستخدم للعمل الهدف بدلا

خصائص أعلن

ويجب عادة استخدام ميزة خصائص أعلن الهدف-C 2.0 لجميع الممتلكات الخاصة بك. إذا لم تكن العامة، وإضافتها في الملحق فئة. باستخدام خصائص أعلن يجعل دلالات إدارة الذاكرة يتضح على الفور، ويجعل من الأسهل بالنسبة لك للتحقق طريقة dealloc بك - إذا كنت مجموعة الإعلانات الممتلكات الخاصة بك معا يمكنك مسح عليها بسرعة ومقارنتها مع تنفيذ طريقة dealloc بك

ويجب أن نفكر مليا قبل لا وسم خصائص باسم 'nonatomic. كما الهدف C برمجة الملاحظات دليل اللغة أو الخصائص الذري افتراضيا، وتكبد النفقات كبيرا. وعلاوة على ذلك، ببساطة جعل كل ما تبذلونه من الخصائص الذرية لا تجعل طلبك موضوع آمن. نلاحظ أيضا، بطبيعة الحال، أنه إذا لم تقم بتحديد "nonatomic" وتنفيذ طرق استرجاع الخاصة بك (بدلا من الجامع لهم)، يجب تنفيذها بطريقة الذري.

فكر القيم معدومة

هذا السؤال الملاحظات، رسائل إلى nil صالحة في الهدف-C. ومع أن هذا هو في كثير من الأحيان ميزة - الرائدة إلى رمز الطبيعي أنظف وأكثر - ميزة يمكن أن تؤدي في بعض الأحيان إلى أخطاء غريبة ويصعب المسار إلى أسفل إذا كنت تحصل على قيمة nil عندما لم تكن تتوقع ذلك.

استخدم NSAssert والأصدقاء. يمكنني استخدام شيء كائن صالح كما في كل وقت ... وخصوصا إرسال رسائل إلى لا شيء غير صحيح تماما في الكائنات C. ولكن إذا كنت حقا تريد أن تجعل متأكدة من حالة متغير، وأنا استخدم NSAssert وNSParameterAssert، مما يساعد على تعقب المشاكل بسهولة.

وبسيطة ولكن المنسية كثيرا واحدة. وفقا للمواصفات:

<اقتباس فقرة>   

في عام، أساليب مختلفة في   الفئات التي لها نفس محدد   (نفس الاسم) يجب أيضا مشاركة   نفس العودة وحجة أنواع. هذه   تفرض قيود من قبل المترجم   للسماح للدينامية ملزمة.

في هذه الحالة كل نفس محددات اسمه، على حتى لو ، أو سيتم اعتبار في فئات مختلفة لدينا أنواع عودة / حجة مماثلة. هنا مثال بسيط.

@interface FooInt:NSObject{}
-(int) print;
@end

@implementation FooInt
-(int) print{
    return 5;
}
@end

@interface FooFloat:NSObject{}
-(float) print;
@end

@implementation FooFloat
-(float) print{
    return 3.3;
}
@end

int main (int argc, const char * argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];    
    id f1=[[FooFloat alloc]init];
    //prints 0, runtime considers [f1 print] to return int, as f1's type is "id" and FooInt precedes FooBar
    NSLog(@"%f",[f1 print]);

    FooFloat* f2=[[FooFloat alloc]init];
    //prints 3.3 expectedly as the static type is FooFloat
    NSLog(@"%f",[f2 print]);

    [f1 release];
    [f2 release]
    [pool drain];

    return 0;
}   

إذا كنت تستخدم ليوبارد (ماك OS X 10.5) أو في وقت لاحق، يمكنك استخدام أدوات التطبيق لإيجاد وتتبع التسرب في الذاكرة. بعد بناء البرنامج في كسكودي، حدد تشغيل> ابدأ مع أداة الأداء> التسريبات.

وحتى إذا لم التطبيق تظهر أي تسرب، قد حفظ الأشياء المحيطة وقتا طويلا. في الأدوات، يمكنك استخدام أداة ObjectAlloc لهذا الغرض. حدد أداة ObjectAlloc في الوثيقة الأدوات الخاصة بك، وطرح التفاصيل الصك (إذا كان لا يظهر بالفعل) عن طريق اختيار عرض> التفاصيل (يجب أن يكون علامة الاختيار بجانبه). تحت عنوان "عمر تخصيص" في التفاصيل ObjectAlloc، تأكد من اختيار زر الاختيار بجوار "مكون والذين لا يزالون يعيشون".

والآن كلما قمت بإيقاف تسجيل طلبك، واختيار أداة ObjectAlloc سوف تظهر لك كم من المراجع هناك على كل كائن ما زالوا يعيشون في التطبيق الخاص بك في العمود "# نت". تأكد من أنك لا تنظر فقط في الطبقات الخاصة بك، ولكن أيضا فئات من الأشياء المستوى الأعلى الملفات NIB. على سبيل المثال، إذا كان لديك أي النوافذ على الشاشة، وأنت ترى ما يشير إلى NSWindow ما زالوا يعيشون، قد لم إصدارها في التعليمات البرمجية.

وتنظيف في dealloc.

وهذا هو واحد من أسهل الأمور أن ننسى - إسبانيا. عندما الترميز في 150mph. دائما، دائما، دائما تنظيف سمات المتغيرات الخاصة بك / عضو في dealloc.

وأود أن استخدام Objc 2 سمات - <م> مع النقطة تدوين جديد - لذلك هذا يجعل عملية التنظيف غير مؤلم. في كثير من الأحيان بسيطة مثل:

- (void)dealloc
{
    self.someAttribute = NULL;
    [super dealloc];
}

وهذا سوف تأخذ الرعاية من الإفراج لك وتعيين السمة إلى NULL (الذي أعتبره البرمجة الدفاعية - في حالة طريقة أخرى إلى مزيد من الانخفاض في dealloc يصل متغير العضو مرة أخرى - نادر ولكن قد يحدث ).

ومع GC تشغيل في 10.5، وهذا ليست هناك حاجة لذلك أي أكثر بكثير - ولكن قد لا تزال بحاجة إلى تنظيف الموارد الآخرين التي تقوم بإنشائها، يمكنك أن تفعل ذلك في طريقة وضع الصيغة النهائية بدلا

وجميع هذه التعليقات هي كبيرة، ولكن أنا ذكر أحد بالدهشة حقا جوجل دليل أسلوب موضوعي-C التي نشرت قبل فترة. أعتقد أنهم قاموا بعمل دقيق للغاية.

وكذلك الموضوعات ذات الصلة شبه (مع غرفة للمزيد من الردود!):

<وأ href = "https://stackoverflow.com/questions/146297/what-are-those-little-xcode-tips-tricks-you-wish-you-knew-about-2-years-ago" > ما هي هذه النصائح كسكودي قليلا وحيل كنت ترغب في عرف قبل حوالي 2 سنوات؟ .

ولا ننسى أن NSWindowController وNSViewController سوف الافراج عن الأجسام على مستوى عال من الملفات NIB أنها تحكمه.

إذا يدويا تحميل ملف طرف مستدق، فأنت مسؤول عن الافراج عن أن الأجسام على مستوى عال طرف مستدق عند الانتهاء معهم.

واحد واحد واضح وليس للمبتدئين في استخدام: استخدام ميزة لصناعة السيارات في المسافة البادئة كسكودي للالتعليمات البرمجية. حتى لو كنت نسخ / لصق من مصدر آخر، وبمجرد الانتهاء من لصق التعليمات البرمجية، يمكنك تحديد كتلة كاملة من التعليمات البرمجية، انقر على الحق في ذلك، ثم اختر الخيار لإعادة البادئة كل شيء داخل تلك الكتلة.

وكسكودي وتحليل الواقع من خلال هذا الباب وبمحاذاة أطراف على أساس أنها الأقواس، الحلقات، وما إلى ذلك من أكثر فعالية بكثير من ضرب على شريط المسافة أو مفتاح تبويب لكل وكل سطر.

وأنا أعلم أنني أغفلت هذه عند الحصول لأول مرة في البرمجة الكاكاو.

تأكد من أنك تفهم مسؤوليات إدارة الذاكرة فيما يتعلق الملفات NIB. أنت مسؤول عن الافراج عن الأجسام على مستوى عال في أي ملف NIB قمت بتحميل. قراءة <لأ href = "http://developer.apple.com/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/chapter_3_section_6.html#//apple_ref/doc/uid/10000051i-CH4-DontLinkElementID_12" يختلط = "نوفولو noreferrer" > وثائق أبل حول هذا الموضوع.

وتشغيل جميع التحذيرات مجلس التعاون الخليجي، ثم إيقاف تلك التي تنتج بشكل منتظم من قبل رؤوس أبل للحد من الضوضاء.

وأيضا تشغيل رنة تحليل ثابت في كثير من الأحيان. يمكنك تمكينه لجميع يبني عبر "تشغيل ثابت محلل" وضع البناء.

وحدة الاختبارات الكتابة وتشغيلها مع كل بناء.

المتغيرات والخصائص

1/ الحفاظ على رؤوسك نظيفة وإخفاء التنفيذ
لا تقم بتضمين متغيرات المثيلات في رأسك.يتم وضع المتغيرات الخاصة في استمرار الفصل كخصائص.يتم الإعلان عن المتغيرات العامة كخصائص عامة في رأسك.إذا كان يجب أن يكون للقراءة فقط، أعلن أنه للقراءة فقط واستبدله بالقراءة والكتابة في استمرار الفصل.في الأساس، أنا لا أستخدم المتغيرات على الإطلاق، بل الخصائص فقط.

2/ قم بتسمية خصائصك باسم متغير غير افتراضي، على سبيل المثال:


@synthesize property = property_;

السبب 1:سوف تصطدم بالأخطاء الناجمة عن نسيان "الذات". عند تعيين العقار.السبب 2:من خلال تجاربي، يواجه محلل التسرب في الأدوات مشاكل في اكتشاف خاصية التسرب بالاسم الافتراضي.

3/ لا تستخدم مطلقًا الاحتفاظ أو الإصدار مباشرة على الممتلكات (أو فقط في حالات استثنائية للغاية).في Dealloc الخاص بك فقط قم بتعيين صفر لهم.يُقصد بالاحتفاظ بالخصائص التعامل مع الاحتفاظ/الإصدار بأنفسهم.أنت لا تعرف أبدًا ما إذا كان أداة الضبط لا تقوم، على سبيل المثال، بإضافة أو إزالة المراقبين.يجب عليك استخدام المتغير مباشرة فقط داخل أداة الضبط و getter الخاصة به.

الآراء

1/ ضع كل تعريف للعرض في xib، إذا استطعت (الاستثناء عادة ما يكون المحتوى الديناميكي وإعدادات الطبقة).إنه يوفر الوقت (إنه أسهل من كتابة التعليمات البرمجية)، ومن السهل تغييره ويحافظ على نظافة التعليمات البرمجية الخاصة بك.

2/ لا تحاول تحسين المشاهدات من خلال تقليل عدد المشاهدات.لا تقم بإنشاء UIImageView في التعليمات البرمجية الخاصة بك بدلاً من xib لمجرد أنك تريد إضافة عروض فرعية إليه.استخدم UIImageView كخلفية بدلاً من ذلك.يمكن لإطار العرض التعامل مع مئات المشاهدات دون مشاكل.

3/ ليس من الضروري الاحتفاظ بـ IBOutlets (أو قوية) دائمًا.لاحظ أن معظم IBOutlets الخاصة بك هي جزء من التسلسل الهرمي للعرض الخاص بك وبالتالي يتم الاحتفاظ بها ضمنيًا.

4/ قم بتحرير جميع IBOutlets في viewDidUnload

5/ اتصل بـ viewDidUnload من طريقة إلغاء التخصيص الخاصة بك.ولا يطلق عليه ضمنا.

ذاكرة

1/ كائنات الإصدار التلقائي عند إنشائها.تحدث العديد من الأخطاء بسبب نقل استدعاء الإصدار إلى فرع if-else واحد أو بعد بيان الإرجاع.يجب استخدام الإصدار بدلاً من الإصدار التلقائي فقط في المواقف الاستثنائية - على سبيل المثال.عندما تنتظر حلقة تشغيل ولا تريد أن يتم إصدار كائنك تلقائيًا في وقت مبكر جدًا.

2/ حتى إذا كنت تستخدم العد المرجعي التلقائي، فيجب عليك أن تفهم تمامًا كيفية عمل طرق الاحتفاظ بالإصدار.إن استخدام الاحتفاظ بالإصدار يدويًا ليس أكثر تعقيدًا من ARC، ففي كلتا الحالتين عليك التفكير في التسريبات ودورات الاحتفاظ.فكر في استخدام الاحتفاظ بالإصدار يدويًا في المشروعات الكبيرة أو التسلسلات الهرمية المعقدة للكائنات.

تعليقات

1/ قم بتوثيق الكود الخاص بك تلقائيًا.يجب أن يوضح كل اسم متغير واسم الطريقة ما يفعله.إذا تمت كتابة التعليمات البرمجية بشكل صحيح (تحتاج إلى الكثير من التدريب في هذا)، فلن تحتاج إلى أي تعليقات على التعليمات البرمجية (ليست مثل التعليقات التوثيقية).يمكن أن تكون الخوارزميات معقدة ولكن الكود يجب أن يكون بسيطًا دائمًا.

2/ في بعض الأحيان، سوف تحتاج إلى تعليق.عادة لوصف سلوك التعليمات البرمجية غير الواضح أو الاختراق.إذا شعرت أنه عليك كتابة تعليق، حاول أولاً إعادة كتابة الكود ليكون أبسط ودون الحاجة إلى التعليقات.

المسافة الفارغة

1/ لا تزيد المسافة البادئة أكثر من اللازم.يجب وضع مسافة بادئة لمعظم كود الطريقة على مستوى الطريقة.الكتل المتداخلة (إذا، وما إلى ذلك) تقلل من سهولة القراءة.إذا كان لديك ثلاث كتل متداخلة، فيجب أن تحاول وضع الكتل الداخلية في طريقة منفصلة.لا ينبغي أبدًا استخدام أربع كتل متداخلة أو أكثر.إذا كان معظم رمز الطريقة الخاص بك موجودًا داخل if، فقم بإلغاء شرط if، على سبيل المثال:


if (self) {
   //... long initialization code ...
}

return self;


if (!self) {
   return nil;
}

//... long initialization code ...

return self;

فهم كود C، وخاصة بنيات C

لاحظ أن Obj-C ليس سوى طبقة OOP خفيفة فوق لغة C.يجب أن تفهم كيفية عمل هياكل التعليمات البرمجية الأساسية في لغة C (التعدادات والبنيات والمصفوفات والمؤشرات وما إلى ذلك).مثال:


view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, view.frame.size.height + 20);

بالضبط مثل:


CGRect frame = view.frame;
frame.size.height += 20;
view.frame = frame;

و أكثر من ذلك بكثير

حافظ على وثيقة معايير الترميز الخاصة بك وقم بتحديثها بشكل متكرر.حاول أن تتعلم من الأخطاء الخاصة بك.افهم سبب إنشاء الخطأ وحاول تجنبه باستخدام معايير الترميز.

تحتوي معايير الترميز لدينا حاليًا على حوالي 20 صفحة، وهي عبارة عن مزيج من معايير ترميز Java ومعايير Google Obj-C/C++ والإضافات الخاصة بنا.قم بتوثيق الكود الخاص بك، واستخدم المسافة البادئة القياسية والمسافات البيضاء والأسطر الفارغة في الأماكن الصحيحة وما إلى ذلك.

كن اكثر وظيفي.

لغة Objective-C هي لغة موجهة للكائنات، ولكن إطار عمل Cocoa مدرك للأسلوب الوظيفي، ويتم تصميمه بأسلوب وظيفي في كثير من الحالات.

  1. هناك فصل للتغير.يستخدم غير قابل للتغيير الفئات ككائن أساسي، والكائن القابل للتغيير ككائن ثانوي.على سبيل المثال، استخدم NSArray بشكل أساسي، واستخدم NSMutableArray فقط عند الحاجة.

  2. هناك وظائف نقية.ليس كثيرًا، يمكنك شراء العديد من واجهات برمجة التطبيقات الإطارية المصممة كوظيفة خالصة.انظر إلى وظائف مثل CGRectMake() أو CGAffineTransformMake().من الواضح أن شكل المؤشر يبدو أكثر كفاءة.لكن الحجة غير المباشرة مع المؤشرات لا يمكن أن تقدم خالية من الآثار الجانبية.تصميم الهياكل بحتة قدر الإمكان.افصل بين كائنات الحالة.يستخدم -copy بدلاً من -retain عند تمرير قيمة إلى كائن آخر.لأن الحالة المشتركة يمكن أن تؤثر على التحول إلى القيمة في كائن آخر بصمت.لذلك لا يمكن أن تكون خالية من الآثار الجانبية.إذا كان لديك قيمة من كائن خارجي، فقم بنسخها.لذلك من المهم أيضًا تصميم الحالة المشتركة بأقل قدر ممكن.

ومع ذلك، لا تخف من استخدام الوظائف غير النقية أيضًا.

  1. هناك تقييم كسول.ترى شيئا من هذا القبيل -[UIViewController view] ملكية.لن يتم إنشاء العرض عند إنشاء الكائن.سيتم إنشاؤه عند قراءة المتصل view الملكية لأول مرة. UIImage لن يتم تحميله حتى يتم رسمه بالفعل.هناك العديد من التنفيذ مثل هذا التصميم.يعد هذا النوع من التصميمات مفيدًا جدًا لإدارة الموارد، ولكن إذا كنت لا تعرف مفهوم التقييم البطيء، فليس من السهل فهم سلوكه.

  2. هناك إغلاق.استخدم الكتل C قدر الإمكان.هذا سوف يبسط حياتك إلى حد كبير.لكن اقرأ مرة أخرى عن إدارة كتلة الذاكرة قبل استخدامها.

  3. يوجد GC شبه تلقائي.NSAutoreleasePool.يستخدم -autorelease أساسي.استخدم الدليل -retain/-release الثانوية عندما تحتاج حقا.(السابق:تحسين الذاكرة، حذف الموارد الصريحة)

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