自定义 NSObject 的共享实例由于某种原因丢失
老实说,我遇到了一个让我很困惑的问题。
我有一个 MAOrders 的共享实例,当我第一次在特定视图控制器中 initWithNibName 时,我会获取该实例。
共享实例使用 NSFileManager 保存到设备,并且一切正常。我可以获取保存的数据和所有这些,这不是问题,但它可能会影响真正的问题,所以请记住这一点......
现在一切都很好,变量ordersController获取这个对象并且该对象被分配给该变量。
然而,当我最终呈现该视图控制器时,ordersController 变量指向任何内容,并导致严重崩溃。
这可能是什么造成的?
编辑
这就是正在发生的事情。在 initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundleOrNil
中,我使用 MAOrders
的共享实例分配 ordersController
,这是一个自定义 NSObject 。 如果我 NSLog 这个对象,我会收到以下信息:
现在,在 viewDidAppear:(BOOL)animated
中,应用程序崩溃。然后我检查ordersController 等于什么并得到以下信息:0x6b3e080 似乎没有指向有效对象。
我哪里出错了?
另一次编辑 这是 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 文件。
I've run into an issue which is confusing me a lot to tell you the truth.
I have a shared instance of MAOrders which I grab when I first initWithNibName in a specific view controller.
The shared instance is saved to the device using NSFileManager and that all works correctly. I can grab the saved data and all of that, that isn't an issue, but it could be effecting what the real problem is so keep that in mind...
Now this is all well and good, the variable ordersController gets this object and the object is allocated to that variable.
However, when I finally present that view controller, the ordersController variable points to nothing and it causes a major crash.
What could be doing this?
EDIT
This is what is happening. In initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundleOrNil
I allocate ordersController
with a shared instance of MAOrders
which is a custom NSObject.
If I NSLog this object, I receive the following: <MAOrders: 0x6b3e080>
Now, in viewDidAppear:(BOOL)animated
the application crashes. I then check what ordersController is equal to and get the following: 0x6b3e080 does not appear to point to a valid object.
Where am I going wrong?
ANOTHER EDIT
Here is the MAOrders singleton code.
//
// 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
That's the complete .m file.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
可能导致此问题的唯一原因是保留和释放数量不平衡。也许当您创建 MAObjects 的共享实例时,它会自动释放,并在调用 initWithNib... 后释放,或者您可以分配 MAObject 的共享实例而不保留它,然后释放它。
没有真正的代码就不可能说。只需找到调用共享 MAObject 的所有位置并检查保留/释放调用即可。您还可以将断点放在 MAObject 的 dealloc 内,然后查看它实际被销毁的位置。
The only reason that may cause this problem is unbalanced number of retains and releases. Maybe when you're creating the shared instance of MAObjects it is autoreleased and gets released after the initWithNib... is called or you could assign shared instance of MAObject without retaining it and then released that.
It's impossible to say without the real code. Just find all places where the shared MAObject is called and check the retain/release calls. You can also put the breakpoint inside the dealloc of MAObject and see where it is actually destroyed.