سؤال

لقد قمت ببعض الاختبارات ، وأحد احتياجاتي هو قراءة البيانات من ملفات XML المختلفة وتكديسها معًا على ملف واحد. على الرغم من أنني تمكنت من تحقيق ذلك ، يبدو أن استهلاك الذاكرة كبير جدًا لهذه المهمة ، إلا أن جهاز iPhone Simulator لم يرفع تحذير الذاكرة ، لكنني لا أعتقد أن iPhone الحقيقي سوف يتسامح مع هذا (ليس لدي هذا جهاز لتجربته هنا ، لذلك أنا في الغالب أتحمل ذلك مما قرأته).
يشبه الجزء الرئيسي من الكود):

Boolean success = [fileManager createFileAtPath:documentsPath contents:nil attributes:nil];
[fileManager release];

if (success) {
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:documentsPath];
    for (int i = 0; i < 100; i++) {

        NSString *path = [[NSBundle mainBundle] pathForResource:@"mensagem_de_arquivo" 
                                                         ofType:@"xml"];
        NSData *data = [NSData dataWithContentsOfFile:path];
        GDataXMLDocument *xml = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil];
        NSArray *tokens = [xml nodesForXPath:@"//message/data" error:nil];
        if (tokens.count > 0) {
            GDataXMLElement *token = (GDataXMLElement *)[tokens objectAtIndex:0];
            [fileHandle writeData:[[token stringValue] dataUsingEncoding:NSASCIIStringEncoding]];
        }
        [xml release];
    }

لا يعطيني استخدام أمر "Build and Analyze" أي تسرب أو أي شيء ، ولا يرفع الرمز تحذيرات عند البناء ، ولكن لا يزال استهلاك الذاكرة يتراوح بين 50 و 70 ميجابايت (مجرد التفكير في البايتات الحية ، بشكل عام يتضاعف تقريبًا).
من الواضح أن الفكرة لا تقرأ 100 مرة من نفس الملف ، ولكن كاختبار بياناته أكثر من الكافيين ، يجب على الكود قراءة المحتويات من ملفات XML فقط وإرسالها إلى ملف بالترتيب الذي يتم استلامه.

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

يحرر - فقط لجعل الأمور أكثر إثارة للاهتمام: سيكون من الأفضل الحفاظ على محلل واحد للقراءة والكتابة ، ومن خلال ذلك الأفضل هو التمسك بـ gdataxml أو ، إذا كان هناك حاجة إلى تغيير ، لاستخدام KissXML libxml - DOM ، والتي يبدو أنها تمتص المزيد من الذاكرة ، كما قال هنا, ، لذلك إذا كانت هناك طريقة لفرض إصدار الذاكرة فسيكون ذلك هو الأفضل.

شكرا مقدما :)

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

المحلول

في الواقع ، لقد كان حلًا بسيطًا جدًا.

كل ما كان علي فعله هو إنشاء مثيل للسيارات وتصريفه في نهاية الحلقة.
مثله:

for (int i = 0; i < 100; i++) {
    NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init];
    //... do everything I've done before...
    [pool drain];
}

أجبر هذا على إطلاق كائنات تم وضع علامة عليها على أنها تم تأسيسها داخل The For ، والتي تم إطلاقها للتو بعد نهاية الأمر ، كما كان متوقعًا ، دون التدخل في كل شيء آخر ، لذلك لم يتم إطلاق أي أشياء قبل ذلك.
انخفض استهلاك الذاكرة من 60 ميغابايت من 60 ميغابايت إلى شيء مثل 1،6 ميجابايت خلال الحلقة ، والعودة إلى نفس 600 كيلو بايت بعد ذلك (كان تطبيق وهمية القيام بذلك فقط).

ما زلت أترك هذا السؤال مفتوحًا لفترة من الوقت ، في حال كان لدى شخص ما فكرة أفضل ، ولكن في الوقت الحالي ، يبدو أن هذا سيكون الطريق :)

نصائح أخرى

نعم ، لقد "تضاعفت" من خلال قراءتها جميعًا في NSDATA ، ثم التحليل في DOM في GDATAXMLDOCUMITY. إذا كنت تتوقع أن تمر بالكثير من بيانات XML مثل هذا ، فالحلق على ملفات متعددة ، وما إلى ذلك ، فيجب عليك ذلك النظر في تحليل ساكس المستند إلى ساكس بدلاً من ذلك, ، وتدفقه مباشرة من الملف بدلاً من التحميل المسبق له في NSDATA. وبهذه الطريقة ، لن تضطر إلى "إصدار كائنات مؤقتة" لأنك ستستخرج فقط المعلومات التي تحتاجها ، حيث يتم تحليلها.

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