由于某种原因,自定义NSObject的共享实例会丢失

时间:2011-11-09 00:03:56

标签: iphone objective-c nsobject

我遇到了一个让我很难说实话的问题。

我有一个MAOrders的共享实例,当我在特定视图控制器中第一次使用initWithNibName时,我会抓住它。

使用NSFileManager将共享实例保存到设备,并且一切正常。我可以抓住保存的数据和所有这些,这不是问题,但它可能会影响真正的问题所以请记住这一点......

现在这一切都很好,变量ordersController获取此对象,并将对象分配给该变量。

但是,当我最终呈现该视图控制器时,ordersController变量指向任何内容并导致严重崩溃。

这可以做什么?

修改
这就是正在发生的事情。在initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundleOrNil中,我为ordersController分配了MAOrders的共享实例,这是一个自定义的NSObject。 如果我NSLog这个对象,我收到以下内容:<MAOrders: 0x6b3e080>

现在,在viewDidAppear:(BOOL)animated应用程序崩溃了。然后我检查ordersController是什么等于并获得以下内容:0x6b3e080 does not appear to point to a valid object.

我哪里错了?

另一个编辑 这是MAOrders单例代码。

//
//  Created by Sebastien Peek on 3/11/11.
//  Copyright (c) 2011 NetStart. All rights reserved.
//

#import "MAOrders.h"
#import "MAOrder.h"

@implementation MAOrders
@synthesize pastOrders, currentOrders;

static MAOrders *ordersState;

+ (id)sharedMAOrdersInstance {

@synchronized(self) {

    if (!ordersState) {

        NSLog(@"Order State");

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
        NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
        NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"Data"];

        NSString *dataFileString = [dataPath stringByAppendingPathComponent:@"Orders.archive"];

        NSData *data = [[NSData alloc] initWithContentsOfFile:dataFileString];
        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
        [data release];

        ordersState = [[unarchiver decodeObjectForKey:@"MAOrders"] retain];
        [unarchiver finishDecoding];
        [unarchiver release];

    }

    if (!ordersState) {
        ordersState = [[MAOrders alloc] init];

    }
}

return ordersState;
} 


- (id)init {

if ([pastOrders count] == 0) {

    pastOrders = [[NSMutableArray alloc] initWithObjects: nil];

}

if ([currentOrders count] == 0) {

    currentOrders = [[NSMutableArray alloc] initWithObjects: nil];

}

return self;

}

- (void)addOrderToPastOrders:(MAOrder *)pastOrder {

[pastOrders addObject:pastOrder];
[self performSelector:@selector(postSaveNotification)];

}

- (void)removeOrderFromPast:(MAOrder *)removeOrder {

[pastOrders removeObject:removeOrder];
[self performSelector:@selector(postSaveNotification)];
// [removeOrder clearAllItems];

}

- (void)addOrderToCurrentOrders:(MAOrder *)currentOrder {

NSLog(@"Current Orders: %@", currentOrders);

[currentOrders addObject:currentOrder];
[self performSelector:@selector(postSaveNotification)];

}

- (void)removeOrderFromCurrent:(MAOrder *)removeOrder {

[currentOrders removeObject:removeOrder];
[self performSelector:@selector(postSaveNotification)];
// [removeOrder clearAllItems];

}

- (void)addOrderFromCurrentToPast:(MAOrder *)currentToPast {

[currentOrders removeObject:currentToPast];
[pastOrders addObject:currentToPast];

[self performSelector:@selector(postSaveNotification)];

}

- (void)postSaveNotification {

[[NSNotificationCenter defaultCenter] postNotificationName:@"ordersNeedToSave" object:nil];

}

- (void)dealloc {



}

#pragma mark NSCoding

#define kPastOrders         @"pastOrders"
#define kCurrentOrders      @"currentOrders"

- (void) encodeWithCoder:(NSCoder *)encoder {

NSLog(@"Orders Encoding");

[encoder encodeObject:pastOrders forKey:kPastOrders];
[encoder encodeObject:currentOrders forKey:kCurrentOrders];

}

- (id)initWithCoder:(NSCoder *)decoder {

NSLog(@"Orders Decoding");

if ((self = [super init])) {

    pastOrders = [decoder decodeObjectForKey:kPastOrders];
    currentOrders = [decoder decodeObjectForKey:kCurrentOrders];

    NSLog(@"CURRENT ORDERS: %@", currentOrders);
    NSLog(@"ORDER MENU NAME: %@", [[[currentOrders objectAtIndex:0] menu] name]);
    NSLog(@"PAST ORDERS: %@", pastOrders);

}

return self;

}


@end

这是完整的.m文件。

1 个答案:

答案 0 :(得分:1)

可能导致此问题的唯一原因是保留和释放的数量不平衡。也许当你创建MAObjects的共享实例时,它会被自动释放并在调用initWithNib ...之后被释放,或者你可以分配MAObject的共享实例而不保留它然后释放它。

没有真正的代码就不可能说。只需找到调用共享MAObject的所有位置,然后检查保留/释放调用。您还可以将断点放在MAObject的dealloc中,并查看它实际销毁的位置。