繁体   English   中英

为什么会收到“未知班级”警告?

[英]Why am I getting this “No known class” warning?

我有一个简单的测试应用程序,可以帮助我学习如何将数据从NSMutableArray持久化到plist。 一切似乎都运行良好,直到我尝试通过在AppDelegate.m文件中调用一个名为“ saveData”的ViewController方法来保存数据之前:

- (void)applicationDidEnterBackground:(UIApplication *)application
{

    [ViewController saveData];
}

我得到了“选择器'saveData'的未知类方法,尽管该方法已在ViewController.h中明确声明,如下所示:

//
//  ViewController.h
//  PlistTest
//
//  Created by Tim Jones on 10/30/13.
//  Copyright (c) 2013 TDJ. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@property (weak, nonatomic) IBOutlet UILabel *nameLabel;

@property (weak, nonatomic) IBOutlet UILabel *timeLabel;

@property NSMutableArray *mainActivityArray;



- (IBAction)buttonHit:(id)sender;

-(NSString *) getFilePath;
-(void) saveData;
-(void) loadData;


@end

并在ViewController.m中实现,因此:

//
//  ViewController.m
//  PlistTest
//
//  Created by Tim Jones on 10/30/13.
//  Copyright (c) 2013 TDJ. All rights reserved.
//

#import "ViewController.h"
#import "DataClass.h"

@interface ViewController ()

@end

@implementation ViewController

-(NSString *) getFilePath
{
    NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    return [[pathArray objectAtIndex:0] stringByAppendingPathComponent:@"PlistTestData"];
}

-(void) saveData
{
    [self.mainActivityArray writeToFile: self.getFilePath atomically:YES];
}

我将ViewController.h导入AppDelegate.h。

我很绿,所以我希望问题对于这里的许多人来说可能是显而易见的。 希望能得到一些帮助。

问题:

[ViewController saveData];

您正在使用类名称ViewController调用saveData方法。
但是saveData是实例方法,而不是类方法。

-(void) saveData;

修正:

1)将saveData声明为类方法

+(void) saveData;

2)使用ViewController的对象调用saveData

ViewController *vControl = [[ViewController alloc] init];
[vControl saveData];

先前的答案(Midhun#2)可以工作,但我认为使用“应用程序确实输入后台通知”并跳过委托会更好。

只需将其添加到“视图确实已加载”:只要应用程序进入后台,它将调用saveData。

[[NSNotificationCenter defaultCenter] addObserver:自我选择器:@selector(saveData)名称:UIApplicationDidEnterBackgroundNotification对象:无];

希望这可以帮助。

正如其他人指出的那样,您的问题是[ViewController saveData]方法调用明确表明您正在尝试调用“ 类方法 ”,并且无疑要调用“实例方法”(因为这是您的视图实例)具有您要保存的数据的控制器)。 为此,您有两个基本选择:

  1. 您可以让您的应用程序委托在视图控制器中调用saveData方法。

    在各种评论中,您提到您“尝试过以我能想象的所有方式实例化VC”。 别。 Midhun的示例是一个概念性示例,说明了类方法和实例方法之间的区别。 但是,当您要调用实例方法时,您想为视图控制器的现有实例调用此方法,绝对不要实例化新的视图控制器。

    因此,您可能会问,如何获得对视图控制器的现有实例的引用? 您要做的是(a)在应用程序委托中创建一个属性,以使用saveData方法保存对视图控制器的saveData (b)让该视图控制器设置应用程序委托的该属性。 因此,首先,在您的应用程序委托的.h文件中创建一个属性以引用视图控制器:

     @property (weak, nonatomic) ViewController *viewController; 

    显然,不要忘记在.h文件中的#import "ViewController.h"行。

    其次,让视图控制器的viewDidLoad方法更新应用程序委托的viewController属性:

     - (void)viewDidLoad { [super viewDidLoad]; AppDelegate *delegate = [[UIApplication sharedApplication] delegate]; delegate.viewController = self; } 

    同样,不要忘记在ViewController.m文件顶部#import "AppDelegate.h"

    完成此操作后,应用程序委托的applicationDidEnterBackground现在可以引用您在viewDidLoad设置的此属性。

     - (void)applicationDidEnterBackground:(UIApplication *)application { [self.viewController saveData]; } 

    坦白说,如果您使用了这种技术,我可能会建议您进一步完善,尤其是采用委托协议模式,但是我将把讨论推迟到您掌握了上述技术之后。

  2. 比上述方法更容易的是,完全消除此应用程序委托applicationDidEnterBackground代码,只让您的视图控制器本身响应与应用程序进入后台相关的系统通知。 而且,不用说,您可以将此代码直接放在视图控制器中。

     - (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveData) name:UIApplicationDidEnterBackgroundNotification object:nil]; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil]; } - (void)saveData { // save your data here } 

    如您所见,我在viewDidLoad注册以观察UIApplicationDidEnterBackgroundNotification ,但还要确保在dealloc删除观察者。 我还确保我的@selector方法名称与我的方法名称完全匹配(例如,在我的示例中,没有参数,因此也没有冒号)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM