EXC_BAD_ACCESS当我关闭我的窗口,这也是我的应用程序的委托 [英] EXC_BAD_ACCESS when I close my window, which is also my application's delegate

查看:182
本文介绍了EXC_BAD_ACCESS当我关闭我的窗口,这也是我的应用程序的委托的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个Cocoa应用程序,当我关闭一个应用程序窗口时,我遇到了 EXC_BAD_ACCESS 错误。我读到这个错误通常意味着内存的问题,但我有 ARC模式开,我不需要关心释放e.t.c. (xCode禁止我调用此函数并自动管理内存)。



错误指向行返回NSApplicationMain )argv);



这是我的应用程序的代码:



.h文件:

  @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文件:

  @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);
}

Dream类:


$ b b

  @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

出了什么问题,为什么我提醒我有xCode 4自动引用计数(ARC)



感谢



UPDATE



我使用个人资料查找zombie事件。所以我发现了这个:一个Objective-C消息发送到一个释放对象(zombie,地址为0x108d85230)



code> [NSApplication(NSWindowCache)_checkForTerminateAfterLastWindowClosed:saveWindows:]



我在代码中有这个功能:

   - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender {
return TRUE;
}



但是在我把它放在注释中后,这个僵尸事件继续发生。

解决方案

崩溃是由于你使窗口成为你的应用程序的代理,当你关闭窗口时,这是最后一个版本,杀死它,如果它是最后一个窗口因为你刚刚杀掉的窗口是应用程序的委托,你会得到那个崩溃。



我对您后续问题的解答中的解决方案较长解释和建议。


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.

解决方案

The crash is caused by the fact that you made the window your application's delegate. When you close the window, that is the last release that kills it off, and if it's the last window you had up, it causes the application to ask its delegate whether it should quit. Since the window you just killed off is the application's delegate, you get that crash.

Longer explanation and suggestion of solution in my answer on your subsequent question.

这篇关于EXC_BAD_ACCESS当我关闭我的窗口,这也是我的应用程序的委托的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆