سؤال

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

في الوظيفة التي تقوم بالتحميل لدي

Venue *venue = [Venue sharedVenue];
NSData *data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
venue = [unarchiver decodeObjectForKey:@"Venue"];
[unarchiver finishDecoding];

مع هذا الرمز، ماذا يعود decoeobjectforkey؟ لا يمكن أن يكون حقا مثالا آخر في المكان ولا يتم تحميله في أي من القيم المحفوظة. قبل أن أتحول ذلك إلى توفير Singleton وكان التحميل كان يعمل بشكل جيد.

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

المحلول

هنا حيث أعتقد أن هذا يحدث خطأ. أنت على دراية NSCODING وتبنيها عادة بجعل جسمك قابل للتطبيق عبر Encodewithcoder: و InitWithcoder: تجاوز. ما سيجعل هذا أكثر بساطة هو أنه لا يزال بإمكانك استخدام NSCODING، و NSCoders دون تجاوز تلك الأساليب. يمكنك ترميز حالة الكائن المشترك دون ترميز OBEJCT المشترك نفسه. هذا يمنع السؤال المحرج عن فك الكائن المشترك.

إليك مثال على ما أعتقد أنه يمكنك القيام به:

@implementation MySharedObject
+ (id)sharedInstance {
    static id sharedInstance = nil;
    if (!sharedInstance) {
        sharedInstance = [[MyClass alloc] init];
    }
}

- (id)init {
    if ((self = [super init])) {
        NSData *data = /* probably from user defaults */
        if (data) { // Might not have any initial state.
            NSKeyedUnarchiver *coder = [[[NSKeyedUnarchiver alloc] initForReadingWithData:data] autorelease];
            myBoolean = [coder decodeBoolForKey:@"MyBoolean"];
            myObject = [[coder decodeObjectForKey:@"MyObject"] retain];
            [coder finishDecoding];
        }
    }
    return self;
}

- (void)saveState {
    NSMutableData *data = [NSMutableData data];
    NSKeyedArchiver *coder = [[[NSKeyedArchiver alloc] initForWritingWithMutableData:data] autorelease];
    [coder encodeBool:myBoolean forKey:@"MyBoolean"];
    [coder encodeObject:myObject forKey:@"MyObject"];
    [coder finishEncoding]
    // Save the data somewhere, probably user defaults...   
}
@end

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

نصائح أخرى

تحتاج إلى القيام بالتحميل في Singleton نفسه ما يحدث هنا هو إنشاء واحد، يمكنك تعيين Lval إلى Singleton، ثم إنشاء كائن جديد وإعادة تعيين LVAL إلى هذا الكائن الجديد دون تعديل Singleton. بعبارات أخرى:

//Set venue to point to singleton
Venue *venue = [Venue sharedVenue];

//Set venue2 to point to singleton
Venue *venue2 = [Venue sharedVenue];

NSData *data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];

//Set venue to unarchived object (does not change the singleton or venue2)
venue = [unarchiver decodeObjectForKey:@"Venue"];
[unarchiver finishDecoding];

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

static Venue *gSharedVenue = nil;

- (Venue *) sharedVenue {
  if (!gSharedVenue) {
    gSharedVenue = [[Venue alloc] init];
  }

  return gSharedVenue;
}

على افتراض أن الحالة التي تريد تغييرها لتحميل الكائن في الدعم العالمي Singleton:

static Venue *gSharedVenue = nil;

- (Venue *) sharedVenue {
  if (!gSharedVenue) {
    NSData *data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]];
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    [data release];

    gSharedVenue = [unarchiver decodeObjectForKey:@"Venue"];
    [unarchiver finishDecoding];
    [unarchiver release];
  }

  if (!gSharedVenue) {
    gSharedVenue = [[Venue alloc] init];
  }

  return gSharedVenue;
}

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

تحرير بناء على تعليق:

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

- (id) init {
  self = [super init];

  if (self) {
    NSData *data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]];
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    [data release];

    Venue *storedVenue = [unarchiver decodeObjectForKey:@"Venue"];
    [unarchiver finishDecoding];
    [unarchiver release];

    if (storeVenue) {
       [self release];
       self = [storedVenue retain];
    }

  }

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