[英]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]
方法调用明确表明您正在尝试调用“ 类方法 ”,并且无疑要调用“实例方法”(因为这是您的视图实例)具有您要保存的数据的控制器)。 为此,您有两个基本选择:
您可以让您的应用程序委托在视图控制器中调用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]; }
坦白说,如果您使用了这种技术,我可能会建议您进一步完善,尤其是采用委托协议模式,但是我将把讨论推迟到您掌握了上述技术之后。
比上述方法更容易的是,完全消除此应用程序委托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.