无法识别的选择器发送到实例"问题

ant*_*kes 2 iphone cocoa-touch objective-c

我的代码在途中突然出现,并在使用导航栏按钮时崩溃.

错误信息: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIView newMemoViewController:didAddMemo:]: unrecognized selector sent to instance 0x5b55a60'

在调试时,程序会运行该cancel方法,并在该@synthesize行引发异常.但是,我看不出它有什么问题.

症状是相同的,所以我只包括Cancel按钮的相关代码:

NewMemoViewController.h

#import <UIKit/UIKit.h>
@protocol NewMemoDelegate;


@class AKVoiceMemo;


@interface NewMemoViewController : UIViewController {
    @private
        AKVoiceMemo *voiceMemo;
        id <NewMemoDelegate> delegate;
}

@property (nonatomic, retain) AKVoiceMemo *voiceMemo;
@property (nonatomic, assign) id <NewMemoDelegate> delegate;

@end

@protocol NewMemoDelegate <NSObject>
- (void)newMemoViewController:(NewMemoViewController *)newMemoViewController didAddMemo:(AKVoiceMemo *)voiceMemo;


@end
Run Code Online (Sandbox Code Playgroud)

NewMemoViewController.m

#import "NewMemoViewController.h"

@synthesize delegate;


- (void)viewDidLoad {
    UIBarButtonItem *cancelButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStyleBordered target:self action:@selector(cancel)];
    self.navigationItem.leftBarButtonItem = cancelButtonItem;
    [cancelButtonItem release];
}


- (void)cancel {
    [self.delegate newMemoViewController:self didAddMemo:nil];
}
Run Code Online (Sandbox Code Playgroud)

非常感谢您的帮助.

编辑:代表是RootViewController:

- (void)newMemoViewController:(NewMemoViewController *)newMemoViewController didAddMemo:(AKVoiceMemo *)voiceMemo {
    if (voiceMemo){
        // Show the note in a new view controller
        // TODO: Implement this
    }

    [self dismissModalViewControllerAnimated:YES];
}
Run Code Online (Sandbox Code Playgroud)

Jam*_*ton 5

你的代表可能设置NewMemoViewControllerUIView对象,而不是实现该目标NewMemoDelegate的协议.

错误消息告诉您newMemoViewController:didAddMemo:消息已发送到UIView对象,并且UIView对象不知道如何处理它.由于您的cancel方法调用newMemoViewController:didAddMemo:委托,因此委托UIView无法识别newMemoViewController:didAddMemo:消息的对象.换句话说,您的委托是a UIView,它不实现NewMemoDelegate协议.

如果你正确设置了委托,那么@jtbandes就是一个很好的观点:委托可能正在被释放,一个UIView对象占用了相同的内存位置,因此偶然"成为"委托.通过使用assign委托的属性,您正在做正确的事情; 这是相当标准的可可练习.但是,您确实需要确保委托由另一个对象保留,并且对象需要确保委托在需要时保持不变NewMemoViewController.