سؤال

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

NSMutableString *newPath = [NSMutableString stringWithCapacity:42];

أو

NSMutableString *newPath = [[NSMutableString alloc] init];

تحرير ... أيضا

أرى الكثير من الإعلانات المكتوبة على سطرين (أي)

NSMutableString *newPath;
newPath = [NSMutableString stringWithCapacity:42];

أنا شخصيا أفضل الخطوط الواحدة، هل هذا مجرد نمط آخر شخصي؟

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

المحلول

NSMutableString *newPath = [NSMutableString stringWithCapacity:42];

أو

NSMutableString *newPath = [[NSMutableString alloc] init];

هل هناك أي سبب خاص لماذا يجب أن أستخدم واحدة أو أخرى، على وجهها، يبدو الأمر أسهل في استخدام الأول؟

نعم. دائما autorelase على الفور ما لم يكن لديك سبب محدد لعدم.

السبب الأول هو أنه من السهل جدا أن تنسى كتابة release رسالة. إذا قمت بتوصيل الكائن في نفس العبارة التي تنشئها (كما في [[[… alloc] init] autorelease])، من الصعب أن تنسى ذلك وأكثر وضوحا عند القيام به. طرق مصنع الراحة (مثل stringWithCapacity:.

ثانيا، حتى لو كنت تتذكر كتابة منفصلة release رسالة، من السهل عدم ضربها. طريقتان هي عوائد مبكرة:

NSString *str = [[NSString alloc] initWithString:@"foo"];

BOOL success = [str writeToFile:path atomically:NO];
if (!success)
    return;

[str release];

واستثناءات إلقاؤها أو نشرها:

NSString *str = [[NSString alloc] initWithString:@"foo"];

//Throws NSRangeException if str is not in the array or is only in the array as the last object
NSString *otherStr = [myArray objectAtIndex:[myArray indexOfObject:str] + 1];

[str release];

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

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

هو أيضا أفضل أفضل لأنه يعطي المترجم شعور بالحجم؟

إنه أفضل، ولكن ليس لهذا السبب.

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

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

أرى الكثير من الإعلانات المكتوبة على سطرين (أي)

NSMutableString *newPath;
newPath = [NSMutableString stringWithCapacity:42];

أنا شخصيا أفضل الخطوط الواحدة، هل هذا مجرد نمط آخر شخصي؟

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

نصائح أخرى

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

بخلاف ذلك، أنت صحيح: الفرق الوحيد هو مسألة الملكية. أنا تقريبا تقريبا استخدام WithCapacity الأساليب، والكلفة فقط استخدام [NSMutableString string] أو [NSMutableArray array], ، ولكن IMO، إنها حقا مجرد مسألة أسلوب ولن تكسب أو تفقد أي شيء باستخدام واحد على الآخر.

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

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

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

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

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

أود أن أقول كقاعدة عامة تستخدم الثانية عندما يكون لديك سبب وجيه للقيام بذلك.

أنت صحيح على كل نقاطك!

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

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

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

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

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