为什么我的委托方法没有被调用?

时间:2012-05-29 22:30:59

标签: iphone ios uitableview delegates

这可能很简单,但我被困住了!

基本上我有一个父视图和子视图控制器,我正在尝试将数据从子节点传递给父节点。

//子VC界面

@protocol ANSearchGetawayFilterDelegate
    -(void)selectedCell:(NSString *)cellTitle;
@end

@interface ANSearchGetawayFilterViewController : UIViewController <UITableViewDelegate,     UITableViewDataSource, UISearchBarDelegate>
{
   NSString* cellTitle;
}
@property (nonatomic, assign) id<ANSearchGetawayFilterDelegate> delegate;

@end

//子VC实现

@implementation ANSearchGetawayFilterViewController
@synthesize delegate = _delegate;

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
    cellTitle = selectedCell.textLabel.text;
    [[self  delegate] selectedCell:cellTitle];

    [self dismissModalViewControllerAnimated:YES];
}

//父VC接口

#import "ANSearchGetawayFilterViewController.h"

@interface ANGetawayFilterViewController : UIViewController <ANSearchGetawayFilterDelegate>
{
    NSString* _cellText;
}

//父VC实施

   - (id)initWithNibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self)
        {
            // Custom initialization
            ANSearchGetawayFilterViewController *search = [[ANSearchGetawayFilterViewController alloc] init];
            search.delegate = self;
        }
        return self;
    }

//delegate method

    -(void)selectedCell:(NSString *)cellTitle
    {
        _cellText = cellTitle;
        NSLog(@"cell text %@", _cellText);
    } 

永远不会调用委托方法,并且当NSLog为_cellText时,它出现为null ...我做错了什么?谢谢!

5 个答案:

答案 0 :(得分:2)

您最有可能在呈现ANSearchGetawayFilterViewController时创建新实例,而不是在其上配置代理。

当你打电话

ANSearchGetawayFilterViewController *search = [[ANSearchGetawayFilterViewController alloc] init];
search.delegate = self;

您创建了ANSearchGetawayFilterViewController的实例,然后正确设置了代理,您从未将此ANSearchGetawayFilterViewController实例存储在任何位置。所以稍后当你来呈现它时,你再次打电话

ANSearchGetawayFilterViewController *search = [[ANSearchGetawayFilterViewController alloc] init];

它为您提供了一个完全不同的实例,然后您需要再次配置它。例如

ANSearchGetawayFilterViewController *search = [[ANSearchGetawayFilterViewController alloc] init];
ANSearchGetawayFilterViewController *search1 = [[ANSearchGetawayFilterViewController alloc] init];

NSLog(@"%d", search1 == search);

#=> 0

修复您的代码更新

- (BOOL)textFieldShouldBeginEditing:(UITextField*)textField;
{
    BOOL shouldBeginEditing = YES; 
    NSLog(@"text field should begin editing"); 

    ANSearchGetawayFilterViewController *myANSearchGetawayFilterViewController = [[[ANSearchGetawayFilterViewController alloc] init] autorelease]; 
    myANSearchGetawayFilterViewController.delegate = self;    // <--- configure the delegate

    [self presentModalViewController:myANSearchGetawayFilterViewController animated:YES];
    [self closeAllPickers]; 
    return shouldBeginEditing; 
}

我不会把它变成一个ivar,因为你可能会暂时提供这个viewController只是为了选择一些数据然后去掉它,所以每次丢弃它并制作一个新的可能是安全的。 / p>

答案 1 :(得分:0)

相反,正在调用委托方法(因此NSLog())。但是,_cellText为(null),因为传入的值为nil,ergo selectedCell.textLabel.text

答案 2 :(得分:0)

首先,您确定正在调用-selectedCell方法吗?

您可以通过在-tableViewDidSelectRow ...

之前或之后放置NSLog()来完成此操作
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    ...
    NSLog(@"TABLEVIEW DID SELECT ROW BEFORE -> %@ <-", cellTitle);
    [[self  delegate] selectedCell:cellTitle];
    NSLog(@"TABLEVIEW DID SELECT ROW DELEGATE CALLED");
    ...
}

另外,您可能想要进行一些清理(可选)

首先,您正在泄漏初始化方法。使用委托将ANGetawayFilterViewController设置为父类的属性,或者在设置委托后将其释放。

其次,在-tableViewDidSelectRow中,您的代码假定代理编码了-selectedCell方法。如果您没有实现该方法,那么应用程序将导致崩溃。您可以通过检查代理-respondsToSelector...

来阻止此操作
if ([self.delegate respondsToSelector:@selector(selectedCell:)]) {
    [self.delegate selectedCell:cellTitle];
}

第三,委托调用的方法通知parentViewController不遵循委托方法使用的一般模式,-numberOfRowsInSectionUITableViewDelegate)除外。您的方法也应该包含实际的ANFilterGetawayViewController实例:

- (void) filterGetawayViewController:(ANSearchGetawayFilterViewController *) controller didSelectCellWithTitle:(NSString *) title {

    ...

}

可以这样称呼:

[self.delegate filterGetawayViewController:self didSelectCellWithTitle:cellTitle];

答案 3 :(得分:0)

你在使用ARC吗?因为当init函数结束时,您的对象(以及它对代理的引用)将被清除。如果您将搜索变量设置为全局变量(在标题中定义并在代码中初始化它)会发生什么?

答案 4 :(得分:0)

假设您正在使用ARC:

您需要为@property实例保留ANSearchGetawayFilterViewController。它将在调用委托方法时由ARC发布。做这样的事。

@property (strong, nonatomic) ANSearchGetawayFilterViewController *search;
...
@synthesize search = _search;

- (id)initWithNibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self)
    {
        // Custom initialization
        self.search = [[ANSearchGetawayFilterViewController alloc] init];
        self.search.delegate = self;
    }
    return self;
}

与您的问题无关,但最佳做法是在调用之前检查委托是否实际实现了您期望的方法,如下所示:

if ([self.delegate respondsToSelector:@selector(selectedCell:)]) {
    [self.delegate selectedCell:cellTitle];
}