我的代码在途中某处中断,并在使用导航栏按钮时崩溃。
错误信息:*** 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
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];
}
您的帮助将不胜感激。
编辑:委托是
RootViewController
:- (void)newMemoViewController:(NewMemoViewController *)newMemoViewController didAddMemo:(AKVoiceMemo *)voiceMemo {
if (voiceMemo){
// Show the note in a new view controller
// TODO: Implement this
}
[self dismissModalViewControllerAnimated:YES];
}
最佳答案
您可能会将NewMemoViewController
的委托设置为UIView
对象,而不是实现NewMemoDelegate
协议的对象。
错误消息告诉您newMemoViewController:didAddMemo:
消息已发送到UIView
对象,而UIView
对象不知道如何处理它。由于您的cancel
方法在委托上调用newMemoViewController:didAddMemo:
,因此是不能识别UIView
消息的委托(即newMemoViewController:didAddMemo:
对象)。换句话说,您的委托人是UIView
,它没有实现NewMemoDelegate
协议。
如果正确设置了委托,则@jtbandes很有意思:委托可能已被释放,并且UIView
对象正在接管相同的内存位置,因此意外地成为了委托。通过为您的委托使用assign
属性,您做对了事情;这是相当标准的可可做法。但是,您确实需要确保委托被另一个对象保留,并且该对象需要确保委托在NewMemoViewController
需要的情况下一直存在。