【问题标题】:Why is my delegate method not called?为什么我的委托方法没有被调用?
【发布时间】:2012-05-29 22:30:59
【问题描述】:

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

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

//子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 其他地方出现为空......我做错了什么?谢谢!

【问题讨论】:

  • 你能展示你实际展示 childViewController 的位置吗?
  • 确定- (BOOL)textFieldShouldBeginEditing:(UITextField*)textField { BOOL shouldBeginEditing = YES; NSLog(@"text field should begin editing"); ANSearchGetawayFilterViewController *myANSearchGetawayFilterViewController = [[[ANSearchGetawayFilterViewController alloc] init] autorelease]; [self presentModalViewController:myANSearchGetawayFilterViewController animated:YES]; [self closeAllPickers]; return shouldBeginEditing; }

标签: iphone ios uitableview delegates


【解决方案1】:

当您呈现 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 只是为了选择一些数据然后将其删除,因此丢弃它并每次创建一个新数据可能是安全的。

【讨论】:

  • 嗯,所以我在 Parent 的界面中将 ANSearchGetawayFilterViewController* _search; 作为 iVar 完成,然后在实现中完成 _search = [[ANSearchGetawayFilterViewController alloc] init]; _search.delegate = self;。这是你的意思吗?我知道这可能是一个问题,但即使改变了委托方法也不会被调用。无论如何,非常感谢您的意见。
【解决方案2】:

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

【讨论】:

  • 对不起,如果我不清楚,我的意思是我在代码的其他地方NSLog_cellText,这个委托方法中的NSLog永远不会被调用。我想我只是无法弄清楚为什么这个值是 nil,当我将它记录到 Child VC 中时它不是 nil ......那么为什么它没有被传回?谢谢!!
【解决方案3】:

首先,您确定正在调用-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 不遵循委托方法使用的一般模式,-numberOfRowsInSection (UITableViewDelegate) 除外。您的方法也应该包含实际的 ANFilterGetawayViewController 实例:

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

    ...

}

可以这样调用:

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

【讨论】:

  • 第二点有点目标。无论是否有意,都隐含记录了委托必须实现此方法,否则它将使用@required标记...
  • 这里是第一个建议的结果:2012-05-30 00:43:54.264 myAPP[34137:11c03] TABLEVIEW DID SELECT ROW BEFORE -&gt; horse &lt;- 2012-05-30 00:43:54.264 myAPP[34137:11c03] TABLEVIEW DID SELECT ROW DELEGATE CALLED 所以它似乎被称为...我现在正在清理。谢谢您的帮助。还有更多想法为什么它不起作用?
【解决方案4】:

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

【讨论】:

    【解决方案5】:

    假设您使用的是 ARC:

    您需要为您的ANSearchGetawayFilterViewController 实例创建一个保留的@property。 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];
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-13
      • 1970-01-01
      • 2013-12-03
      • 2020-11-28
      相关资源
      最近更新 更多