my code broke somewhere along the way, and crashes when using the navigation bar buttons.
Error message:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIView newMemoViewController:didAddMemo:]: unrecognized selector sent to instance 0x5b55a60'
When de开发者_开发知识库bugging, the program does run the cancel
method, and throws an exception at the @synthesize
line. However, I cannot see anything wrong with it.
The symptoms are identical, so I am including the relevant code only for the Cancel
button:
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];
}
Your help would be appreciated.
Edit: the delegate is the RootViewController
:
- (void)newMemoViewController:(NewMemoViewController *)newMemoViewController didAddMemo:(AKVoiceMemo *)voiceMemo {
if (voiceMemo){
// Show the note in a new view controller
// TODO: Implement this
}
[self dismissModalViewControllerAnimated:YES];
}
You're probably setting the delegate of NewMemoViewController
to a UIView
object instead of an object that implements the NewMemoDelegate
protocol.
The error message is telling you that a newMemoViewController:didAddMemo:
message was sent to a UIView
object and the UIView
object didn't know what to do with it. Since your cancel
method calls newMemoViewController:didAddMemo:
on the delegate, it is the delegate which is the UIView
object that doesn't recognize the newMemoViewController:didAddMemo:
message. In other words, your delegate is a UIView
and it doesn't implement the NewMemoDelegate
protocol.
If you are correctly setting the delegate, then @jtbandes makes a great point: The delegate is probably being released and a UIView
object is taking over the same memory location, thus "becoming" the delegate by accident. You're doing the right thing by using the assign
attribute for your delegate; that's fairly standard Cocoa practice. However, you do need to make sure that the delegate is retained by another object, and that object needs to make sure that the delegate sticks around as long as NewMemoViewController
needs it to.
I'm guessing you've over-released the delegate. I notice you have @property (assign) ... delegate;
. This means that whenever you set the delegate, that object must be retained by something else as well.
The other possibility is the delegate is actually a UIView, but I'm guessing it's the other case.
精彩评论