首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么我会收到这个“未知类”的警告?

为什么我会收到这个“未知类”的警告?
EN

Stack Overflow用户
提问于 2013-11-01 19:10:54
回答 3查看 393关注 0票数 1

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- (void)applicationDidEnterBackground:(UIApplication *)application
{

    [ViewController saveData];
}

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//
//  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中实现,因此:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//
//  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。

我是个新手,所以我希望这个问题对这里的许多人来说是显而易见的。一定会很感谢你的帮助的。

EN

回答 3

Stack Overflow用户

发布于 2013-11-01 19:14:08

问题:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[ViewController saveData];

您正在使用类名ViewController调用saveData方法。

但是saveData是一个实例方法,而不是类方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-(void) saveData;

修复:

1)将saveData声明为类方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
+(void) saveData;

2)使用ViewController的对象调用saveData

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ViewController *vControl = [[ViewController alloc] init];
[vControl saveData];
票数 1
EN

Stack Overflow用户

发布于 2013-11-01 20:55:53

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

只需将此代码添加到"view did load“中:每当应用程序转到后台时,它都会调用saveData。

[选择器添加name:UIApplicationDidEnterBackgroundNotification :自身选择器:@NSNotificationCenter(SaveData)选择器对象:nil];

希望这能有所帮助。

票数 0
EN

Stack Overflow用户

发布于 2013-11-02 06:51:07

正如其他人所指出的,您的问题在于,您的[ViewController saveData]方法调用清楚地表明您正在尝试调用"class method",并且您无疑希望调用您的“实例方法”(因为拥有您要保存的数据的是视图控制器的实例)。要实现这一点,您有两个基本选择:

  1. 你可以让你的应用代理在你的视图控制器中调用saveData方法。

在不同的评论中,你提到你已经“尝试了我能想象到的每一种方式和每一个地方的VC”。不要。Midhun的例子是一个概念性的例子,说明了类和实例方法之间的区别。但是,虽然您希望调用instance方法,但您希望为视图控制器的现有实例调用该方法,而不是实例化新的视图控制器。

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

@property (弱,非原子) ViewController *视图控制器;

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

其次,让视图控制器的viewDidLoad方法更新应用程序委托的委托{ viewController viewDidLoad;AppDelegate *viewController= [UIApplication sharedApplication delegate];delegate.viewController = self;}

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

完成此操作后,应用程序代理的applicationDidEnterBackground现在可以引用您在viewDidLoad

  • (void)applicationDidEnterBackground:(UIApplication *)应用程序{ self.viewController saveData;}中设置的此属性

坦率地说,如果你使用了这种技术,我可能会建议进一步的改进,特别是采用委托协议模式,但我会推迟到你掌握了上面的technique.

  1. Even之后再进行讨论比上面更容易的是完全消除这个应用委托applicationDidEnterBackground代码,让你的视图控制器本身响应与应用进入后台相关的系统通知。而且,不用说,您可以将此代码正确地放入视图控制器itself.
  • (void)viewDidLoad { name:UIApplicationDidEnterBackgroundNotification name:UIApplicationDidEnterBackgroundNotification;[viewDidLoad NSNotificationCenter defaultCenter :self selector:@selector(saveData) name:UIApplicationDidEnterBackgroundNotification viewDidLoad:nil];}-(NSNotificationCenter)dealloc{ [NSNotificationCenter defaultCenter saveData:self NSNotificationCenter object:nil];}-(NSNotificationCenter)saveData{ //在此处保存您的数据}

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19733742

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文