将控制器的委托属性设置为self会导致我的应用程序崩溃

时间:2014-07-22 21:34:26

标签: objective-c cocoa-touch uiviewcontroller uinavigationcontroller delegates

我有3个控制器:

SearchViewController

CollectionViewController

MainViewController

简而言之

在CollectionViewController中,我可以通过点击导航栏中的放大镜来访问SearchViewController。然后我可以搜索特定项目。然后从返回的行中选择一个结果。一旦我点击一行,SearchViewController就被解除,并在CollectionViewController上执行查询。

然而,在MainViewController上,事情并不相同。因为当从MainViewController访问SearchViewController并解雇它时出现的MainViewController因为这是SearchViewController初始化的地方所以我必须做一些额外的工作来让我到CollectionViewController来执行查询。我在第一段演出。

我在MainViewController中设置了一个协议/委托方法,当SearchViewController被解除导致应用程序崩溃时,它会通知CollectionViewController。我无法弄清楚原因。请继续阅读以获得更好的解释。

客户在SearchViewController的搜索框中键入他们想要搜索的内容,当他们点击相关联的tableView中的行时,SearchViewController被解除,并且它的父CollectionViewController现在在屏幕上。当这个控制器被解雇时,我使用一个委托来通知CollectionViewController,SearchViewController被解雇了。

通知CollectionViewController关于解雇SVC然后执行查询:

- (void)searchViewControllerDismissed:(VAGSearchViewController*)searchViewController withTitleForObject:(NSString *)titleString
{
    _searchTitleString = titleString;
    [self setObjects:nil];
    [self performQuery];
}

一切正常。但是我有另一个控制器MainViewController。可以从MainViewController访问SearchViewController,但是当我从CollectionViewController访问SearchViewController时,我无法解除和执行查询,因为当SearchViewController被解除时,MainViewController出现在屏幕上,因为它是我从中访问SearchViewController的控制器。

我决定做的是检测哪个控制器初始化的SearchViewController然后使用上面相同的委托方法在SearchViewController被解除时通知该控制器。

在SearchViewController内部:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 

    // If count of child view controllers is greater than 1 then we are not on main table view controller  
    if ([[[self presentingViewController] childViewControllers] count] > 1) {
        [self dismissViewControllerAnimated:NO completion:^{
        [[self delegate] searchViewControllerDismissed:self withTitleForObject:[[cell textLabel] text]];
    }];
    } else {
        [self dismissViewControllerAnimated:NO completion:^{
        [[self delegate] searchViewControllerDismissed:self withTitleForObject:[[cell textLabel] text]];
        }];
    }
}

这很好用。所以现在我在MainViewController中创建了一个协议。

在MainViewController.h中:

@class VAGMainTableViewViewController;
@protocol VAGMainTableViewControllerDisappearedDelegate <NSObject>
- (void)mainTableViewControllerDisappearedwithTitleForObject:(NSString *)titleString;
@end

@interface VAGMainTableViewController : UITableViewController
@property (nonatomic, weak) id<VAGMainTableViewControllerDisappearedDelegate> disappearDelegate;

我想要的是这个委托方法,然后通知CollectionViewController,SearchViewController已从MainViewController中解除,然后执行查询。

以下是MainViewController.m中的代码:

- (void)searchViewControllerDismissed:(VAGSearchViewController *)searchViewController withTitleForObject:(NSString *)titleString
{
    self.disappearDelegate = self;
    [[self disappearDelegate] mainTableViewControllerDisappearedwithTitleForObject:titleString];
    [self performSegueWithIdentifier:@"garmentsCollectionSegue" sender:nil];
} 

崩溃的原因是:

[VAGMainTableViewController mainTableViewControllerDisappearedwithTitleForObject:]: unrecognized selector sent to instance 0xf0140f0

当我注释掉我设置了lostarDelegate行的行时,崩溃消失了,我被推送到CollectionViewController(garmentsCollectionSegue)。但是,委托方法中传递的数据显然是由CollectionViewController接收的,因为设置了委托。

我已经做了足够多的麻烦,我认为我遇到的问题是由于未正确设置代表或未将其设置在正确的位置造成的。

会感激一些帮助。

感谢您的时间。

1 个答案:

答案 0 :(得分:1)

您似乎将MainViewController设置为自己的委托。我不认为这就是你想要的。

您想使用该委托协议来通知CollectionViewController MainViewController中发生了什么,对吗?

然后CollectionViewController应该是disappearDelegate。

所以请尝试:

CollectionViewController *collectionVC = //this depends on your app structure, get the controller
self.disappearDelegate = collectionVC;