【问题标题】:iOS Use of undeclared identifier in protocol?iOS 在协议中使用未声明的标识符?
【发布时间】:2014-02-19 02:07:44
【问题描述】:

我有两个视图控制器,HomeViewController(以下称为 HVC)和 AddActivityViewController(以下称为 AAVC)。在 AAVC 中,我声明了一个委托协议:

@protocol AddActivityViewControllerDelegate;

并如此定义:

@protocol AddActivityViewControllerDelegate


-(void) addActivityViewControllerDidSave;

-(void) addActivityViewControllerDidCancel:(ListActivity *) activityToDelete;

@end

接下来,我在 HVC(委托)中实现了这两个方法,如下所示:

-(void) addActivityViewControllerDidSave
    {
        [self.moc MR_saveToPersistentStoreAndWait];
        [self.navigationController dismissViewControllerAnimated:YES completion:nil];
    }

-(void) addActivityViewControllerDidCancel:(ListActivity *) activityToDelete
    {
        [activityToDelete MR_deleteEntity];
        [self.navigationController dismissViewControllerAnimated:YES completion:nil];        
    }

我收到此错误“使用未声明的标识符 'addActivityViewControllerDidSave',即使它已在协议中明确声明。

我应该提一下,在此之前,我正在处理显然是一个“导入循环”,它导致了一个“未声明的协议”错误。该错误似乎已修复。

以下是 HomeViewController.h 文件中的 @import 语句:

#import <UIKit/UIKit.h>
#import "ListActivity.h"
#import "AddActivityViewController.h"
#import "TimedActivity.h"

@interface HomeViewController : UIViewController <AddActivityViewControllerDelegate>

@property (strong, nonatomic) IBOutlet UITableView *myTableView;

@property NSManagedObjectContext * moc;

- (IBAction)dumpMemory:(UIButton *)sender;
@end

并且来自 AddActivityViewController.h 文件:

#import <UIKit/UIKit.h>
#import "ListActivity.h"

@protocol AddActivityViewControllerDelegate;


@interface AddActivityViewController : UIViewController

@property (weak, nonatomic) IBOutlet UITextField *activityField;
@property (weak, nonatomic) IBOutlet UITextField *categoryField;

@property (strong, nonatomic) ListActivity *thisActivity;

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

- (IBAction)saveButton:(UIBarButtonItem *)sender;
- (IBAction)cancelButton:(UIBarButtonItem *)sender;

@end

@protocol AddActivityViewControllerDelegate


-(void) addActivityViewControllerDidSave;

-(void) addActivityViewControllerDidCancel:(ListActivity *) activityToDelete;

@end

如果有帮助,我可以发布所有四个类文件的全部内容。

非常感谢您的帮助!

编辑:这是 HomeViewController.m 的完整代码:

//
//  HomeViewController.m
//  MRExample
//
//  Created by Tim Jones on 1/15/14.
//  Copyright (c) 2014 TDJ. All rights reserved.
//

#import "HomeViewController.h"
#import "ListActivity.h"

@interface HomeViewController ()

{
    NSFetchedResultsController *frc;
}


@end

@implementation HomeViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.automaticallyAdjustsScrollViewInsets = NO;

    [self refreshData];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationNewActivityAdded:) name:@"newActivityAdded" object:nil];

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void) notificationNewActivityAdded:(NSNotification*)notification
{
    [self refreshData];
}



#pragma mark Table View data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [[frc sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    id<NSFetchedResultsSectionInfo> sectionInfo = [[frc sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];
}

// Customize the appearance of table view cells.
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {

    // Configure the cell to show the activity's name
    ListActivity *thisActivity = [frc objectAtIndexPath:indexPath];
    cell.textLabel.text = thisActivity.activityName;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    [self configureCell:cell atIndexPath:indexPath];

    cell.textLabel.textColor = [UIColor redColor];
    NSAttributedString *attString;
    attString = cell.textLabel.attributedText;
    return cell;
}


//     Section Label

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    NSString *sectionLabel = [[[frc sections] objectAtIndex:section]name];
    return [sectionLabel uppercaseString];
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
    ListActivity *thisActivity = [frc objectAtIndexPath:indexPath];

    TimedActivity *currentActivity = [TimedActivity MR_createInContext:localContext];
    currentActivity.timedActivityName = thisActivity.activityName;
    currentActivity.category = thisActivity.activityCategory;
    currentActivity.timedActivityTapped = [NSDate date];
    [localContext MR_saveToPersistentStoreAndWait];

}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
        ListActivity *activityToTrash = [frc objectAtIndexPath:indexPath];
        // Delete the row from the data source
        [activityToTrash MR_deleteEntity];
        [localContext MR_saveToPersistentStoreAndWait];
        [self refreshData];
    }
}


-(void) refreshData
{
    //This was the turning point for proper MR grouping. The two Properties (activityCategory and activityName) are used as Sort descriptors in the underlying core data methods
    frc = [ListActivity MR_fetchAllSortedBy:@"activityCategory,activityName" ascending:YES withPredicate:nil groupBy:@"activityCategory" delegate:nil];

    [self.myTableView reloadData];
}



- (IBAction)dumpMemory:(UIButton *)sender
{
    NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
    [ListActivity MR_truncateAllInContext:localContext];
    [localContext MR_saveToPersistentStoreAndWait];

    [self refreshData];
}

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSManagedObjectContext *localContext = [[NSManagedObjectContext alloc] init];
    if ([[segue identifier] isEqualToString:@"addActivity"])
    {
        AddActivityViewController *aavc = (AddActivityViewController *) [segue destinationViewController];
        aavc.delegate = self;
        ListActivity *newActivity = [ListActivity MR_createInContext:localContext];
        aavc.thisActivity = newActivity;
    }

-(void) addActivityViewControllerDidSave
    {
        [self.moc MR_saveToPersistentStoreAndWait];
        [self.navigationController dismissViewControllerAnimated:YES completion:nil];
    }

-(void) addActivityViewControllerDidCancel:(ListActivity *) activityToDelete
    {
        [activityToDelete MR_deleteEntity];
        [self.navigationController dismissViewControllerAnimated:YES completion:nil];        
    }


}
@end

【问题讨论】:

  • 错误信息在哪一行?
  • -(void) addActivityViewControllerDidSave
  • 很抱歉之前没有看到这一点,但我也收到了两个警告,说这两种协议方法都没有实现。
  • 请贴出HVC的完整代码
  • 我可以在评论中发表吗?

标签: ios objective-c protocols delegation


【解决方案1】:

好吧,就像我想的那样。问题是您在- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 方法的末尾缺少一个括号“}”。此外,您在课程末尾有一个额外的括号(在 @end 关键字的正上方)。这可能是缺少的括号。解决这个问题,您的问题就会消失。

希望这会有所帮助!

【讨论】:

  • 就是这样!伙计,我希望编译器会说“缺少“}”括号而不是它所说的。:)
【解决方案2】:

我不知道是不是问题,但是将你的代理声明(使用@class 指令)移到AddActivityViewController的顶部,如下所示:

#import <UIKit/UIKit.h>
#import "ListActivity.h"

@class AddActivityViewController;

@protocol AddActivityViewControllerDelegate
- (void)addActivityViewControllerDidSave;
- (void)addActivityViewControllerDidCancel:(ListActivity *) activityToDelete;
@end

@interface AddActivityViewController : UIViewController

@property (nonatomic, weak) id <AddActivityViewControllerDelegate> delegate;
@property (nonatomic, weak) IBOutlet UITextField *activityField;
@property (nonatomic, weak) IBOutlet UITextField *categoryField;
@property (nonatomic, strong) ListActivity *thisActivity;

- (IBAction)saveButton:(UIBarButtonItem *)sender;
- (IBAction)cancelButton:(UIBarButtonItem *)sender;

@end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多