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

时间:2011-01-08 00:42:43

标签: iphone objective-c cocoa-touch

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

错误讯息: *** 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];
}

2 个答案:

答案 0 :(得分:5)

您可能正在将NewMemoViewController的委托设置为UIView对象,而不是实现NewMemoDelegate协议的对象。

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

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

答案 1 :(得分:1)

我猜你已经过度释放了代表。我注意到你有@property (assign) ... delegate;。这意味着无论何时设置委托,该对象也必须由其他东西保留。

另一种可能性是委托实际上是一个UIView,但我猜它是另一种情况。