Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/98.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 使用NSUserDefaults与Today Extension(小部件)共享自定义对象数组_Ios_Objective C_Widget_Nsuserdefaults_Nscoding - Fatal编程技术网

Ios 使用NSUserDefaults与Today Extension(小部件)共享自定义对象数组

Ios 使用NSUserDefaults与Today Extension(小部件)共享自定义对象数组,ios,objective-c,widget,nsuserdefaults,nscoding,Ios,Objective C,Widget,Nsuserdefaults,Nscoding,这是我的第一篇文章,所以请在回顾我的发帖技巧时保持建设性 基本上,我的问题是我有一个自定义对象数组,需要与today扩展共享。对象表示待办事项列表中的任务,其属性用于存储有关每个任务的信息(名称、位置、截止日期、缩略图等)。对象存储在一个数组中,该数组用于填充我的待办事项列表。我所要做的就是将这个数组传递给我的小部件,这样我就可以填充第二个tableview,它将充当第一个tableview的压缩版本(对于小部件视图) 我应该指出,我的小部件设置正确,因为我已经在“组”中将它和包含它的应用程序正

这是我的第一篇文章,所以请在回顾我的发帖技巧时保持建设性

基本上,我的问题是我有一个自定义对象数组,需要与today扩展共享。对象表示待办事项列表中的任务,其属性用于存储有关每个任务的信息(名称、位置、截止日期、缩略图等)。对象存储在一个数组中,该数组用于填充我的待办事项列表。我所要做的就是将这个数组传递给我的小部件,这样我就可以填充第二个tableview,它将充当第一个tableview的压缩版本(对于小部件视图)

我应该指出,我的小部件设置正确,因为我已经在“组”中将它和包含它的应用程序正确链接在一起。我还成功地使用NSUserDefaults将NSString数组传递给小部件,但是,当我尝试将对象数组传递给小部件时,它会崩溃,并且我的日志读取:

*** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (Xitem)'
我知道这次崩溃与归档对象(Xitem)有关,这似乎是在NSUserDefaults中保存自定义对象的必要步骤。但是,我已经测试过在包含应用程序的同一类中保存/加载数组,效果很好!(代码如下)

好的,如前所述,上面的代码按预期工作。然而,当我将这段代码的第二个“unarchiver”部分插入到我的today小部件中时,我得到了前面提到的错误。下面是我如何编码/解码对象的代码(值得注意的是,创建此对象是为了简化调试,并且仅包含NSString属性):

Xitem.h

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>


@interface Xitem : NSObject <NSCoding> 
{ 
NSString *itemName;
}

-(void)encodeWithCoder:(NSCoder*)encoder;
-(id)initWithCoder:(NSCoder*)decoder;

@property NSString *itemName;

@end
我也可以发布我的小部件并包含应用程序代码,但它与我发布的第一组代码没有区别(除了重命名的变量,如“defaults2”)。我应该指出,在试图解决这个问题时,我确实已经耗尽了资源,但仅在包含NSKeyedArchiver的应用程序中使用NSKeyedArchiver这一事实让我感到困惑

我意识到这与我自己的问题非常相似,但作者决定选择一种变通方法,而我实际上想知道为什么这不起作用。我是一名新的开发人员,我正在尽我最大的努力学习最佳工作实践,因此任何建议都将不胜感激

我想也可以用NSDictionary替换我的对象(类)?然而,如果可能的话,我希望避免这种情况,因为它会在主应用程序中引起许多冲突,但显然,如果这是正确的方法,我将解决这个问题。另一方面,如果出于任何其他原因(例如内存或可访问性),字典比我的需求对象(具有UIImage、CLLocation等属性的待办事项列表)更好,请详细说明并帮助我理解原因


非常感谢任何人的时间:)

好的,所以我刚刚解决了这个问题。如果有人有同样的问题,请转到:“Targets'>'Widget'>'Build Phases'>'Compile Sources'>add custom class here(Xitem.m)

有人为我提供任何输入吗?我把这个问题放在一边,因为它似乎应该这样工作,如果有人知道为什么它不,请指出给我。抱歉,这已经超过一周了。请注意,这会给你的应用程序包添加不必要的副本;实际上,您正在构建两个独立的对象文件,这些文件内联链接到您的应用程序和应用程序扩展名。对于较小的应用程序来说,这不是什么大不了的事情,但重复这种模式会使二进制文件的增长超过需要。最终,我认为一个更好的长期模式是将(应用程序和应用程序扩展之间的通用)代码提取到一个框架中,然后将应用程序和应用程序扩展链接到该框架。
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>


@interface Xitem : NSObject <NSCoding> 
{ 
NSString *itemName;
}

-(void)encodeWithCoder:(NSCoder*)encoder;
-(id)initWithCoder:(NSCoder*)decoder;

@property NSString *itemName;

@end
#import "Xitem.h"

@implementation Xitem

@synthesize itemName;

-(void)encodeWithCoder:(NSCoder*)encoder
{

[encoder encodeObject:self.itemName forKey:@"iName"];

}

-(id)initWithCoder:(NSCoder*)decoder
{

self = [super init];

self.itemName = [decoder decodeObjectForKey:@"iName"];

return self;
}

@end