带有核心数据对象的 NSArray 的单例 null
Posted
技术标签:
【中文标题】带有核心数据对象的 NSArray 的单例 null【英文标题】:Singleton with NSArray of Core data objects null 【发布时间】:2015-11-19 21:08:19 【问题描述】:所以我有一个包含 NSArray 的 Singleton。该数组由来自核心数据获取请求的 120K+ 个对象启动。当我通过数组访问视图控制器中的这些对象时,它们为空。它显示了正确数量的对象,并且在初始化后它们在单例中显示得很好。有什么想法吗?感谢您的帮助。
Singleton.h
@interface Singleton : NSObject
@property (nonatomic, retain) NSArray *singletonArray;
+(Singleton*)singleton;
@end
Singleton.m
#import "Singleton.h"
#import "DataAccessLayer.h"
@implementation Singleton
@synthesize singletonArray;
+(Singleton *)singleton
static dispatch_once_t pred;
static __strong Singleton *shared = nil;
dispatch_once(&pred, ^
shared = [[Singleton alloc]init];
);
return shared;
-(id)init
if (self = [super init])
DataAccessLayer *dataAccess = [[DataAccessLayer alloc]init];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext: dataAccess.managedObjectContext]];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"Name" ascending:YES]]];
NSError *error = nil;
self.singletonArray = [dataAccess.managedObjectContext executeFetchRequest:fetchRequest error:&error];
return self;
@end
ViewController.m
#import "ViewController.h"
#import "Singleton.h"
@interface ViewController ()
@end
- (void)viewDidLoad
[super viewDidLoad];
FAKFontAwesome *settingsIcon = [FAKFontAwesome gearIconWithSize:22];
[settingsIcon addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor]];
UIImage *settingsIconImage = [settingsIcon imageWithSize:CGSizeMake(22, 22)];
UIButton *settingsIconButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 22, 22)];
[settingsIconButton addTarget:self action:@selector(settingsBarButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[settingsIconButton setImage:settingsIconImage forState:UIControlStateNormal];
[self.settingsBarButton setCustomView:settingsIconButton];
self.masterArray = [NSArray new];
self.masterArray = [[Singleton singleton] singletonArray];
NSString *title = [[self.masterArray objectAtIndex:0] field1];
NSLog(@"Viewdidload: %@", title);
- (IBAction)settingsBarButtonClicked:(id)sender
NSString *title = [[self.masterArray objectAtIndex:0] field1];
NSLog(@"SettingsBarButtonClicked Log %@", title);
@end
单例控制台输出
(lldb) po [self.singletonArray count]
120441
(lldb) po [self.singletonArray objectAtIndex:0]
<MyEntity: 0x14c0628c0> (entity: MyEntity; id: 0xd00000070e740000 <x-coredata://8DAFE4F5-7218-4F6F-B32A-1BD9C056D1B9/MyEntity/p115613> ; data:
"field1" = "joe";
"field2" = "doe";
)
ViewController 中的控制台输出
2015-11-19 17:51:09.188 MyApp[20299:7909725] Viewdidload: joe
2015-11-19 17:54:36.637 MyApp[20334:7913246] SettingsBarButtonClicked Log (null)
(lldb) po [self.masterArray count]
120441
(lldb) po [self.masterArray objectAtIndex:0]
<MyEntity: 0x1366db7a0> (entity: <null>; id: 0xd00000070e740000 <x-coredata://8DAFE4F5-7218-4F6F-B32A-1BD9C056D1B9/MyEntity/p115613> ; data: <fault>)
【问题讨论】:
如果您查看第二个 'po` 的输出,您可以看到该对象是fault
;这意味着核心数据将在第一次访问时检索实际对象。您是否尝试过访问其中一个属性?
为什么不在 fetch 上设置批量大小?并显示视图控制器代码。
我更新了代码以显示视图控制器和日志。我确实注意到的一件事是,当在视图中调用单例时,内存会出现很大的峰值,最高可达 145mb。然后,它下降到大约 40mb。 ARC 是否会以某种方式清理单例或核心数据内容?
【参考方案1】:
在我看来,获取所有记录并将它们存储在内存中的数组中是一个非常糟糕的主意。基本上,它违背了数据库的目的。
我建议改用NSFetchedResultsController
来访问您的对象。您将免费获得很多东西:出色的性能、内存优化和许多其他功能,例如用于在保存新数据时更新您的列表,或用于填充表格视图等。
NB:从您的问题看来,数组读取得很好。尝试记录实体的实际“field1”的内容并检查它是否有效。
【讨论】:
我相信使用 Singleton 处理这么多数据的问题是内存问题。我最终创建了一个传递谓词键和值的全局 fetchRequest 方法。这允许我接收基于字段和值的过滤数组。谢谢你的建议以上是关于带有核心数据对象的 NSArray 的单例 null的主要内容,如果未能解决你的问题,请参考以下文章