尝试实现NSTableView委托协议的EXC_BAD_ACCESS

时间:2012-05-19 02:06:04

标签: objective-c delegates exc-bad-access

我正在关注" Mac OS X"的Cocoa编程示例,它解释了如何为NSTableView实现协议。
我试图像书中所做的那样做,但可能我错过了一些东西 有一个NSSpeechSynthesizer和一个文本字段,每次用户按下按钮"说",文本字段的内容由语音合成器说出。还有一个包含所有语音列表的NSTableView,用户可以选择他喜欢的声音 这是代码:

界面:

#import <Cocoa/Cocoa.h>

@interface SpeakLineAppDelegate : NSObject <NSApplicationDelegate, NSSpeechSynthesizerDelegate, NSTableViewDelegate, NSTableViewDataSource> 
{
@private
    NSWindow *window;
    NSTextField *textField;
    NSTableView *tableView;
    NSButton *speakButton;
    NSSpeechSynthesizer* ss;
    NSButtonCell *stopButton;
    NSArray* voices;
}

@property (assign) IBOutlet NSWindow *window;
@property (assign) IBOutlet NSTextField *textField;
@property (assign) IBOutlet NSTableView *tableView;

@property (assign) IBOutlet NSButton *speakButton;

- (IBAction)speak:(id)sender;
- (IBAction)stop:(id)sender;
@property (assign) IBOutlet NSButtonCell *stopButton;


@end

实施:

#import "SpeakLineAppDelegate.h"

@implementation SpeakLineAppDelegate
@synthesize stopButton;
@synthesize textField;
@synthesize tableView;
@synthesize speakButton;

@synthesize window;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application
 }


- (id) init
{
    self=[super init];
    if(self)
    {
        NSLog(@"init method called");
        ss=[[NSSpeechSynthesizer alloc]initWithVoice:nil];
        [ss setDelegate: self];
        voices=[NSSpeechSynthesizer availableVoices];
    }
    return self;
}

- (IBAction)speak:(id)sender 
{
    NSString* str=[textField stringValue];
    if([str length]>0)
    {
        [ss startSpeakingString: str];
        [stopButton setEnabled: YES];
        [speakButton setEnabled: NO];
    }
    else
    {
        NSLog(@"The string has length zero");
    }
}

- (IBAction)stop:(id)sender 
{
    [ss stopSpeaking];
}

- (void) speechSynthesizer:(NSSpeechSynthesizer *)sender didFinishSpeaking:   (BOOL)finishedSpeaking
{
    NSLog(@"Has finished speaking");
    [stopButton setEnabled: NO];
    [speakButton setEnabled: YES];
}

- (NSInteger) numberOfRowsInTableView:(NSTableView *)tableView
{
    return [voices count];
}

- (id) tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
    NSString* str=[voices objectAtIndex: row];
    NSDictionary* dict=[NSSpeechSynthesizer attributesForVoice: str];
    return [dict objectForKey: NSVoiceName];
}


- (void)tableViewSelectionDidChange:(NSNotification *)notification
{
    NSInteger row=[tableView selectedRow];
    if(row!=-1)
    {
        NSString* str=[voices objectAtIndex: row];
        [ss setVoice: str];
        NSLog(@"New voice: %@",str);
    }
}

@end

我还在xib文件中完成了以下操作:
- 我已经连接了NSTableView的选项&#34;数据源&#34;和#34;委托&#34;到SpeakLineAppDelegate(我的应用程序的文件名)。
IBOutlet textField与xib文件中的NSTextField链接,同时说出和停止是为xib文件中的按钮设置的操作。
NSTableView是IBOutlet&#34; tableView&#34;,也是这个链接在xib文件中。
问题:此时我得到了EXC_BAD_ACCESS:

- (id) tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
    NSString* str=[voices objectAtIndex: row];  // here I get the exception
    NSDictionary* dict=[NSSpeechSynthesizer attributesForVoice: str];
    return [dict objectForKey: NSVoiceName];
}

我无法确定此异常的原因,因为声音是在init方法中分配的 使用gdb如果我在抛出异常时尝试打印行的值,它会打印为零,所以我真的不知道我的代码有什么问题。

0 个答案:

没有答案