委托方法未被调用或调用时未触发
Delegate method not being called or not firing when called
我正在尝试实现两个委托方法。我认为我的协议编写正确,并且我正确地分配了委托,因为我在另一个工作正常的 delegate/protocol 上仔细地建模了它。但是,委托方法在调用时不会触发,或者至少看起来是这样。我在调用委托方法的地方设置了断点,也在方法本身设置了断点,但似乎控制永远不会到达它们。
这是我认为相关的代码。来自 notifyingVC.h 文件:
// AddCategoryVC.h
// YYYYYY
//
// Created by XXXXXX on 2/19/15.
// Copyright (c) 2015 XXXXXX. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "WMMGCategory.h"
//#import "AddTransactionVC.h"
@class AddTransactionVC;
@protocol AddCategoryDelegate <NSObject>
-(void) addCategoryDidSave : (WMMGCategory *) brandNewCategory;
-(void) addCategoryDidCancel : (WMMGCategory *) categoryToDelete;
@end
@interface AddCategoryVC : UIViewController
@property (nonatomic, weak) id <AddCategoryDelegate> delegate;
来自 notifyingVC.m 文件:
// AddCategoryVC.m
// YYYYYY
//
// Created by XXXXXX on 2/19/15.
// Copyright (c) 2015 XXXXXX. All rights reserved.
//
#import "AddCategoryVC.h"
#import "WMMGCategory.h"
@interface AddCategoryVC ()
@end
@implementation AddCategoryVC
…Blah de blah…
- (IBAction)saveCategory:(UIBarButtonItem *)sender
{
if (self.nooCatTextField.text.length < 1)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"New category not identified"
message:@"Please enter a name for the new category or cancel"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
else
{
self.brandNewCategory.name = [self.nooCatTextField.text uppercaseString];
[self.delegate addCategoryDidSave:self.brandNewCategory];
}
}
- (IBAction)cancelCategory:(UIBarButtonItem *)sender
{
[self.delegate addCategoryDidCancel:self.brandNewCategory];
}
来自 DelegateVC.h 文件:
//
// AddTransactionVC.h
// YYYYYY
//
// Created by XXXXXX on 2/6/15.
// Copyright (c) 2015 XXXXXX. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <MagicalRecord/CoreData+MagicalRecord.h>
#import "WMMGTransaction.h"
#import "AddCategoryVC.h"
#import "WMMGCategory.h"
来自DelegateVC.m header:
//
// AddTransactionVC.m
// YYYYYY
//
// Created by XXXXXXXX on 2/6/15.
// Copyright (c) 2015 XXXXXX. All rights reserved.
//
#import "AddTransactionVC.h"
@interface AddTransactionVC ()
@end
@implementation AddTransactionVC
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
AddCategoryVC *acvc = [[AddCategoryVC alloc]init];
acvc.delegate = self;
}
最后,在 DelegateVC.m 文件中,委托方法本身:
#pragma mark - New category delegate methods
-(void)addCategoryDidSave:(WMMGCategory *)brandNewCategory
{
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
[localContext MR_saveToPersistentStoreAndWait];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
-(void)addCategoryDidCancel:(WMMGCategory *)categoryToDelete
{
[categoryToDelete MR_deleteEntity];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
我先承认我可能犯了一些愚蠢的错字之类的,但我非常感谢有人看看我做错了什么。
编辑,根据@rdelmar 下面的回答:
这是 AddCategoryVC 实例的创建代码:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSString *identifier = segue.identifier;
if ([identifier isEqualToString:@"CatSelectSegue"])
{
UIViewController *dvc = segue.destinationViewController;
UIPopoverPresentationController *catSelPPC = dvc.popoverPresentationController;
if (catSelPPC)
{
catSelPPC.delegate = self;
}
}
else if ([identifier isEqualToString:@"newCatSegue"])
{
UIViewController *dvc = segue.destinationViewController;
UIPopoverPresentationController *catNewPPC = dvc.popoverPresentationController;
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
if ([[segue identifier] isEqualToString:@"newTransSegue"])
{
UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
AddCategoryVC *addCatVC = (AddCategoryVC *)navController.topViewController;
addCatVC.delegate = self;
WMMGCategory *addedCategory = (WMMGCategory *)[WMMGCategory MR_createInContext:localContext];
addCatVC.brandNewCategory = addedCategory;
}
if (catNewPPC)
{
catNewPPC.delegate = self;
}
}
}
你的问题是你在 viewDidLoad 中创建了一个 AddCategoryVC 的实例,它不是你在屏幕上的实例(你永远不会对它做任何事情,所以它会在 viewDidLoad 超出范围后立即被释放)。您需要获得对已有实例的引用。在不知道您在哪里制作控制器以及它们如何出现在屏幕上的情况下,我无法具体说明如何做到这一点。
我正在尝试实现两个委托方法。我认为我的协议编写正确,并且我正确地分配了委托,因为我在另一个工作正常的 delegate/protocol 上仔细地建模了它。但是,委托方法在调用时不会触发,或者至少看起来是这样。我在调用委托方法的地方设置了断点,也在方法本身设置了断点,但似乎控制永远不会到达它们。
这是我认为相关的代码。来自 notifyingVC.h 文件:
// AddCategoryVC.h
// YYYYYY
//
// Created by XXXXXX on 2/19/15.
// Copyright (c) 2015 XXXXXX. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "WMMGCategory.h"
//#import "AddTransactionVC.h"
@class AddTransactionVC;
@protocol AddCategoryDelegate <NSObject>
-(void) addCategoryDidSave : (WMMGCategory *) brandNewCategory;
-(void) addCategoryDidCancel : (WMMGCategory *) categoryToDelete;
@end
@interface AddCategoryVC : UIViewController
@property (nonatomic, weak) id <AddCategoryDelegate> delegate;
来自 notifyingVC.m 文件:
// AddCategoryVC.m
// YYYYYY
//
// Created by XXXXXX on 2/19/15.
// Copyright (c) 2015 XXXXXX. All rights reserved.
//
#import "AddCategoryVC.h"
#import "WMMGCategory.h"
@interface AddCategoryVC ()
@end
@implementation AddCategoryVC
…Blah de blah…
- (IBAction)saveCategory:(UIBarButtonItem *)sender
{
if (self.nooCatTextField.text.length < 1)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"New category not identified"
message:@"Please enter a name for the new category or cancel"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
else
{
self.brandNewCategory.name = [self.nooCatTextField.text uppercaseString];
[self.delegate addCategoryDidSave:self.brandNewCategory];
}
}
- (IBAction)cancelCategory:(UIBarButtonItem *)sender
{
[self.delegate addCategoryDidCancel:self.brandNewCategory];
}
来自 DelegateVC.h 文件:
//
// AddTransactionVC.h
// YYYYYY
//
// Created by XXXXXX on 2/6/15.
// Copyright (c) 2015 XXXXXX. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <MagicalRecord/CoreData+MagicalRecord.h>
#import "WMMGTransaction.h"
#import "AddCategoryVC.h"
#import "WMMGCategory.h"
来自DelegateVC.m header:
//
// AddTransactionVC.m
// YYYYYY
//
// Created by XXXXXXXX on 2/6/15.
// Copyright (c) 2015 XXXXXX. All rights reserved.
//
#import "AddTransactionVC.h"
@interface AddTransactionVC ()
@end
@implementation AddTransactionVC
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
AddCategoryVC *acvc = [[AddCategoryVC alloc]init];
acvc.delegate = self;
}
最后,在 DelegateVC.m 文件中,委托方法本身:
#pragma mark - New category delegate methods
-(void)addCategoryDidSave:(WMMGCategory *)brandNewCategory
{
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
[localContext MR_saveToPersistentStoreAndWait];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
-(void)addCategoryDidCancel:(WMMGCategory *)categoryToDelete
{
[categoryToDelete MR_deleteEntity];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
我先承认我可能犯了一些愚蠢的错字之类的,但我非常感谢有人看看我做错了什么。
编辑,根据@rdelmar 下面的回答:
这是 AddCategoryVC 实例的创建代码:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSString *identifier = segue.identifier;
if ([identifier isEqualToString:@"CatSelectSegue"])
{
UIViewController *dvc = segue.destinationViewController;
UIPopoverPresentationController *catSelPPC = dvc.popoverPresentationController;
if (catSelPPC)
{
catSelPPC.delegate = self;
}
}
else if ([identifier isEqualToString:@"newCatSegue"])
{
UIViewController *dvc = segue.destinationViewController;
UIPopoverPresentationController *catNewPPC = dvc.popoverPresentationController;
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
if ([[segue identifier] isEqualToString:@"newTransSegue"])
{
UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
AddCategoryVC *addCatVC = (AddCategoryVC *)navController.topViewController;
addCatVC.delegate = self;
WMMGCategory *addedCategory = (WMMGCategory *)[WMMGCategory MR_createInContext:localContext];
addCatVC.brandNewCategory = addedCategory;
}
if (catNewPPC)
{
catNewPPC.delegate = self;
}
}
}
你的问题是你在 viewDidLoad 中创建了一个 AddCategoryVC 的实例,它不是你在屏幕上的实例(你永远不会对它做任何事情,所以它会在 viewDidLoad 超出范围后立即被释放)。您需要获得对已有实例的引用。在不知道您在哪里制作控制器以及它们如何出现在屏幕上的情况下,我无法具体说明如何做到这一点。