在 prepareForSeque 时委托不是 nil,但在导航表视图中调用时为 nil

Posted

技术标签:

【中文标题】在 prepareForSeque 时委托不是 nil,但在导航表视图中调用时为 nil【英文标题】:Delegate not nil when prepareForSeque, but nil when called in Navigation Table View 【发布时间】:2015-02-05 03:23:55 【问题描述】:

我有一个在具有表格视图的导航控制器中创建的委托。当我从 MainViewController(我已将其设置为委托并实现委托方法)传递数据时,我通过 prepareForSegue 进行。看起来像这样:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

    if ([segue.identifier isEqualToString:@"loadFavorites"]) 
        FavoritesTableViewController *favoriteTableViewcontroller = segue.destinationViewController;
        favoriteTableViewcontroller.delegate = self;
    

在同一个 MainViewcontroller 类中,我在 .h 文件中执行此操作:

@interface MainViewController : UITableView <UITextFieldDelegate, FavoriteTableViewControllerDelegate>

我还在 FavoriteTableViewController 类中声明了以下内容:

@class FavoritesTableViewController;

@protocol FavoriteTableViewControllerDelegate <NSObject>
- (void)favoriteTableViewController:(FavoritesTableViewController *)controller didSelectItem:(NSString *) item;
@end

@interface FavoritesTableViewController : UITableViewController

@property (nonatomic, weak) id <FavoriteTableViewControllerDelegate> delegate;

@end

我在我的 MainViewController 中实现了协议:

- (void)favoriteTableViewController:(FavoritesTableViewController *)controller didSelectItem:(NSString *)item

    self.item.text = [stop substringToIndex:5];

    [self dismissViewControllerAnimated:YES completion:nil];

一切都编译好了,我可以看到委托正在设置。但是,这里的tableView委托中调用方法时:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    selectedIndex = indexPath.row;
    NSString *key = favorites[indexPath.row];
    NSString *item = [[FavoritesData getAllFavoriteItems] objectForKey:key];

    [self.delegate favoriteTableViewController:self didSelectItem:item];

委托设置为 0x0 或 nil。这意味着它不会回调 MainViewController 类来执行代码。我还有一个星期的代表团。我知道它是如何工作的,但是当它不工作时,我通常会有点迷失。我做错了什么?

顺便说一句,在故事板中,NavigationController 中有一个 TableViewController,它将类设置为 FavoriteTableViewController。这一切都很好,因为我正在使用 NSUserDefaults 将数据传递给模态视图。我现在要做的就是选择数据,关闭视图,然后将数据设置到主视图。

【问题讨论】:

segue 是否会转到导航控制器?您是否尝试过在 [segue.identifier isEqualToString:@"loadFavorites"] if 语句中添加日志?我不知道有多少次我没有把正确的字符串放在那里检查。 是的,它将进入导航控制器。 我为您发布了一个答案,但没有解释为什么在您设置委托时它没有崩溃。希望对您有所帮助。 您的委托正在被释放...所以您应该将 mainVC 保留在某个地方...尽管您已经描述了它被释放的奇怪之处,因为它位于 Nav 堆栈中。暂时,也许在你的应用程序委托单例中保留一个指向它的指针。如果这是问题,请考虑将其作为永久参考。或者将逻辑更改为不依赖导航堆栈中控制器之间的委托。 【参考方案1】:

如果您要使用导航控制器,您应该首先获得导航。但是,如果您设置委托,它应该会崩溃。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

    if ([segue.identifier isEqualToString:@"loadFavorites"]) 
        UINavigationController *navController = segue.destinationViewController;

        FavoritesTableViewController *favoriteTableViewcontroller = navController.childViewControllers[0];
        favoriteTableViewcontroller.delegate = self;
    

【讨论】:

【参考方案2】:

您的 MainViewController 是否也嵌入在导航控制器中?

如果没有,它可能会在委托方法调用之前被释放。

尝试暂时将代理设置为strong,看看这是否会有所作为。不要忘记将其改回弱,以避免之后的潜在保留周期。

【讨论】:

将其设置为 strong 没有帮助。 MainViewController 也位于 TabBar 控制器中,而不是嵌入在导航控制器中。我只是导航控制器的续集(这可能是我的问题,我不知道)。

以上是关于在 prepareForSeque 时委托不是 nil,但在导航表视图中调用时为 nil的主要内容,如果未能解决你的问题,请参考以下文章

iOS:当应用程序因任何崩溃而退出时,是不是有任何委托方法

当某些参数是委托时,是不是可以在 C# 中使用“C++ 库函数”?

为所有对象创建一个委托,而不是为每个对象创建一个委托

当准确性提高时,是不是有 CoreLocation 通知或委托方法?

委托是不是具有每次应用程序来自后台时执行的功能

委托元素是不是需要获得焦点才能触发键盘事件?