I wrote a Cocoa Application and I got EXC_BAD_ACCESS
error when I'm closing an application window. I read that this error usually means problems with memory, but I have ARC mode
on and I don't need care about releasing e.t.c. (xCode forbids me to call this functions and manage memory automatically).
Error is pointing at line return NSApplicationMain(argc, (const char **)argv);
in main function.
Here's my application's code:
.h file:
@interface MainDreamer : NSWindow <NSWindowDelegate>
{
NSTextField *dreamField;
NSTableView *dreamTable;
NSImageView *dreamview;
NSMutableArray *dreamlist;
NSMutableArray *dataset;
}
@property (nonatomic, retain) IBOutlet NSTextField *dreamField;
@property (nonatomic, retain) IBOutlet NSTableView *dreamTable;
@property (nonatomic, retain) IBOutlet NSImageView *dreamview;
@property (nonatomic, retain) IBOutlet NSMutableArray *dreamlist;
@property (nonatomic, retain) IBOutlet NSMutableArray *dataset;
@property (assign) IBOutlet NSWindow *window;
@end
.m file:
@implementation MainDreamer
@synthesize window;
@synthesize dataset;
@synthesize dreamField;
@synthesize dreamlist;
@synthesize dreamview;
@synthesize dreamTable;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{
NSString *applicationPath = [[NSBundle mainBundle] bundlePath];
NSString *filename = [applicationPath stringByAppendingPathComponent:@"dreams"];
NSLog(self.description);
dreamlist = [[NSMutableArray alloc] init];
dataset = [[NSMutableArray alloc] init];
dataset = [NSKeyedUnarchiver unarchiveObjectWithFile:filename];
if([dataset count] != 0) {
int i = 0;
while (i < [dataset count]) {
Dream *dr = [[Dream alloc] init];
dr = [dataset objectAtIndex:i];
[dreamlist addObject: dr.dreamname];
i++;
}
}
[dreamTable reloadData];
}
-(void)applicationWillTerminate:(NSNotification *)notification{
NSString *applicationPath = [[NSBundle mainBundle] bundlePath];
NSString *filename = [applicationPath stringByAppendingPathComponent:@"dreams"];
[NSKeyedArchiver archiveRootObject:dataset toFile:filename];
NSLog(@"finish");
}
- (void) mouseUp:(NSEvent *)theEvent{
long index = [dreamTable selectedRow];
Dream *dr = [[Dream alloc] init];
dr = [dataset objectAtIndex:index];
dr.dreampicture = dreamview.image;
[dataset replaceObjectAtIndex:index withObject:dr];
NSLog(self.description);
}
- (void) tableViewSelectionDidChange: (NSNotification *) notification{
long row = [dreamTable selectedRow];
Dream *dr = [[Dream alloc] init];
dr = [dataset objectAtIndex: row];
if(dr.dreampicture != NULL)
dreamview.image = dr.dreampicture;
NSLog(@"selected row changed");
}
Class "Dream":
@interface Dream : NSObject <NSCoding>
{
NSString *dreamname;
NSImage *dreampicture;
}
@property (retain) NSString* dreamname;
@property (retain) NSImage* dreampicture;
-(id)initWithCoder:(NSCoder *)aDecoder;
-(void)encodeWithCoder:(NSCoder *)aCoder;
@end
What is wrong, why EXC_BAD_ACCESS
occurs?I remind that I have xCode 4 with Automatic Reference Counting (ARC)
Thanks
UPDATE
I used Profile to find zombie event. So I found out this: An Objective-C message was sent to a deallocated object(zombie( at adress 0x108d85230)
Responsible Caller - [NSApplication(NSWindowCache) _checkForTerminateAfterLastWindowClosed: saveWindows:]
I had this function in code:
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender{
return TRUE;
}
However after I putted it in comments, this zombie event continue to occur.
@property (assign) IBOutlet NSWindow *window;
. Could you explain what this is needed for? Do you use interface builder to link this window to itself? You can justself
in that case... – BarbabraMainDreamer
? As it implementsapplicationDidFinishLaunching
it seems it should be the app delegate, but it is declared as a subclass ofNSWindow
. – BarbabraIBOutlet NSWindow *window;
- it was no necessity in it. As concernsMainDreamer
class - it should be a subclass ofNSWindow
to have mouse events working.It is wired via delegate withFile'S Owner
witch class isNSApplication
. In statistics' object summary there's information that_checkForTerminateAfterLastWindowClosed
invokes afterNSWindow close
andNSWindow release
– Clance