Skip to content

Commit 856fe0f

Browse files
author
Joe Page
committed
- try to improve performance of loading & displaying data:
> remove duplicate call to loadEndityDataAtIndex (assume this was on accident - app appears to work fine w/out it) > remove try/catch logic but still make sure we don't access invalid index (assuming this caused the exception seen before but will keep testing) > return tableView:heightOfRow > enable Core Animation (see http://stackoverflow.com/questions/19962721/why-might-an-nstableview-redraw-every-cell-on-scroll); seems to have a nice speed improvement from my testing so far > log time taken in main thread when you select a row.. still seeing up to 3 secs at times (was 7+ secs) so more needs to be done on background thread - don't set min column size so user can reduce a column with a long title but short data
1 parent c5742cf commit 856fe0f

6 files changed

Lines changed: 101 additions & 63 deletions

File tree

CoreDataUtil.xcodeproj/project.pbxproj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
83AE7D3019FF1AB400DD152B /* SimulatorItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 83AE7D2F19FF1AB400DD152B /* SimulatorItem.m */; };
4040
83AE7D3219FF1CE900DD152B /* simulatorIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 83AE7D3119FF1CE900DD152B /* simulatorIcon.png */; };
4141
83B158FD158F6AE2002B46C2 /* MFLCoreDataIntrospection.m in Sources */ = {isa = PBXBuildFile; fileRef = 83B158FC158F6AE2002B46C2 /* MFLCoreDataIntrospection.m */; };
42+
9780EDFFBC753AD96BBF64A1 /* MFLUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 9780E6C8A039EE9C6DDC7B83 /* MFLUtils.m */; };
4243
C1CEFE561463779D00466EB3 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1CEFE551463779D00466EB3 /* Cocoa.framework */; };
4344
C1CEFE601463779D00466EB3 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C1CEFE5E1463779D00466EB3 /* InfoPlist.strings */; };
4445
C1CEFE621463779D00466EB3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C1CEFE611463779D00466EB3 /* main.m */; };
@@ -59,6 +60,7 @@
5960
C1CEFE9B1463779D00466EB3 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = C1CEFE9A1463779D00466EB3 /* main.c */; };
6061
C1CEFE9D1463779D00466EB3 /* GetMetadataForFile.m in Sources */ = {isa = PBXBuildFile; fileRef = C1CEFE9C1463779D00466EB3 /* GetMetadataForFile.m */; };
6162
C1CEFEA01463779D00466EB3 /* MySpotlightImporter.m in Sources */ = {isa = PBXBuildFile; fileRef = C1CEFE9F1463779D00466EB3 /* MySpotlightImporter.m */; };
63+
DB2F1D8D1A13D0470021E081 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB2F1D8C1A13D0470021E081 /* QuartzCore.framework */; };
6264
DB4F5F561A1257D300ED506D /* CoreDataPro.app in CopyFiles */ = {isa = PBXBuildFile; fileRef = C1CEFE511463779C00466EB3 /* CoreDataPro.app */; };
6365
/* End PBXBuildFile section */
6466

@@ -147,6 +149,8 @@
147149
83AE7D3119FF1CE900DD152B /* simulatorIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = simulatorIcon.png; sourceTree = "<group>"; };
148150
83B158FB158F6AE2002B46C2 /* MFLCoreDataIntrospection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFLCoreDataIntrospection.h; sourceTree = "<group>"; };
149151
83B158FC158F6AE2002B46C2 /* MFLCoreDataIntrospection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFLCoreDataIntrospection.m; sourceTree = "<group>"; };
152+
9780E6C8A039EE9C6DDC7B83 /* MFLUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFLUtils.m; sourceTree = "<group>"; };
153+
9780E887DE002F72EABD10EF /* MFLUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFLUtils.h; sourceTree = "<group>"; };
150154
C1CEFE511463779C00466EB3 /* CoreDataPro.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CoreDataPro.app; sourceTree = BUILT_PRODUCTS_DIR; };
151155
C1CEFE551463779D00466EB3 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
152156
C1CEFE581463779D00466EB3 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
@@ -180,13 +184,15 @@
180184
C1CEFE9F1463779D00466EB3 /* MySpotlightImporter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MySpotlightImporter.m; sourceTree = "<group>"; };
181185
C1CEFEA11463779D00466EB3 /* Importer Read Me.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Importer Read Me.txt"; sourceTree = "<group>"; };
182186
C1CEFEA21463779D00466EB3 /* CoreDataUtilImporter-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CoreDataUtilImporter-Prefix.pch"; sourceTree = "<group>"; };
187+
DB2F1D8C1A13D0470021E081 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
183188
/* End PBXFileReference section */
184189

185190
/* Begin PBXFrameworksBuildPhase section */
186191
C1CEFE4E1463779C00466EB3 /* Frameworks */ = {
187192
isa = PBXFrameworksBuildPhase;
188193
buildActionMask = 2147483647;
189194
files = (
195+
DB2F1D8D1A13D0470021E081 /* QuartzCore.framework in Frameworks */,
190196
C1CEFE561463779D00466EB3 /* Cocoa.framework in Frameworks */,
191197
);
192198
runOnlyForDeploymentPostprocessing = 0;
@@ -221,6 +227,8 @@
221227
833FF6FC187860F1003ADCEA /* MFLConstants.m */,
222228
832C9699159BDBB000AC8FA8 /* MFLCoreDataEditorProjectLoader.h */,
223229
832C969A159BDBB000AC8FA8 /* MFLCoreDataEditorProjectLoader.m */,
230+
9780E6C8A039EE9C6DDC7B83 /* MFLUtils.m */,
231+
9780E887DE002F72EABD10EF /* MFLUtils.h */,
224232
);
225233
path = Utils;
226234
sourceTree = "<group>";
@@ -337,6 +345,7 @@
337345
C1CEFE541463779D00466EB3 /* Frameworks */ = {
338346
isa = PBXGroup;
339347
children = (
348+
DB2F1D8C1A13D0470021E081 /* QuartzCore.framework */,
340349
C1CEFE551463779D00466EB3 /* Cocoa.framework */,
341350
C1CEFE761463779D00466EB3 /* SenTestingKit.framework */,
342351
C1CEFE8C1463779D00466EB3 /* CoreServices.framework */,
@@ -648,6 +657,7 @@
648657
5B2BA5C4159C9FEB00AFEC9D /* CoreDataHistoryObject.m in Sources */,
649658
833FF6FD187860F1003ADCEA /* MFLConstants.m in Sources */,
650659
1D52574616EB66F200A91244 /* FetchRequestInfoController.m in Sources */,
660+
9780EDFFBC753AD96BBF64A1 /* MFLUtils.m in Sources */,
651661
);
652662
runOnlyForDeploymentPostprocessing = 0;
653663
};

CoreDataUtil/CoreData/MFLCoreDataIntrospection.m

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//
88

99
#import "MFLCoreDataIntrospection.h"
10+
#import "MFLUtils.h"
1011

1112
NSInteger const CORE_DATA_HISTORY_MAX = 100;
1213

@@ -388,7 +389,9 @@ - (void) clearEntityData {
388389
}
389390

390391
- (void) loadEntityDataAtIndex: (NSUInteger) index {
392+
NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970];
391393
self.entityData = [self fetchObjectsByEntityName:[self entityAtIndex:index]];
394+
NSLog(@"loadEntityDataAtIndex: %@ms", [MFLUtils duration:startTime]);
392395
}
393396

394397
- (NSString*) entityAtIndex:(NSUInteger) index {
@@ -410,7 +413,13 @@ - (NSUInteger) entityDataCount {
410413
}
411414

412415
- (NSArray*) getDataAtRow: (NSUInteger) row {
413-
return (self.entityData)[row];
416+
if (row >= 0 && row < [self entityDataCount]) {
417+
return (self.entityData)[row];
418+
}
419+
else {
420+
NSLog(@"getDataAtRow: bad row:%d", (int)row);
421+
return nil;
422+
}
414423
}
415424

416425
- (NSInteger)getCurrentHistoryIndex
@@ -425,6 +434,7 @@ - (void)setCurrentHistoryIndex:(NSInteger)currentIndex
425434

426435
- (void)updateCoreDataHistory:(NSString *)name predicate:(NSPredicate *)predicate objectType:(MFLObjectType)type
427436
{
437+
NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970];
428438
if (self.coreDataHistory == nil)
429439
{
430440
self.coreDataHistory = [[NSMutableArray alloc] initWithCapacity:CORE_DATA_HISTORY_MAX];
@@ -458,6 +468,7 @@ - (void)updateCoreDataHistory:(NSString *)name predicate:(NSPredicate *)predicat
458468
[self.coreDataHistory removeObjectAtIndex:currentHistoryIndex + 1];
459469
}
460470
}
471+
NSLog(@"updateCoreDataHistory: %@, %@ms", name, [MFLUtils duration:startTime]);
461472
}
462473

463474
@end

CoreDataUtil/MFLMainWindowController.m

Lines changed: 28 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#import "GetInfoSheetController.h"
2020
#import "FetchRequestInfoController.h"
2121
#import "ObjectInfoController.h"
22+
#import "MFLUtils.h"
2223

2324
@interface OutlineViewNode : NSObject
2425
@property (strong) OutlineViewNode *parent;
@@ -143,14 +144,9 @@ - (void)addTableColumnWithIdentifier:(NSString *)ident
143144
[[newColumn headerCell] setTextColor:[NSColor darkGrayColor]];
144145
[[newColumn headerCell] setAlignment:NSCenterTextAlignment];
145146

146-
147-
CGFloat defaultColWidth = [newColumn width];
147+
//CGFloat defaultColWidth = [newColumn width];
148148
[newColumn sizeToFit];
149-
if ([newColumn width] < defaultColWidth)
150-
{
151-
[newColumn setMinWidth:defaultColWidth];
152-
}
153-
149+
154150
[[self entityContentTable] addTableColumn:newColumn];
155151

156152
// TODO: we should set the cells up with proper types when we allow users to edit data
@@ -253,6 +249,8 @@ - (void)tableViewSelectionDidChange:(NSNotification *)aNotification
253249
- (void)onEntitySelected {
254250
if ([self.dataSourceList selectedRow] >= 0)
255251
{
252+
NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970];
253+
256254
[self removeColumns];
257255
[self.coreDataIntrospection clearEntityData];
258256
[self.entityContentTable reloadData];
@@ -262,7 +260,6 @@ - (void)onEntitySelected {
262260

263261
NSInteger selected = selectedNode.index;
264262
NSInteger section = selectedNode.parent.index;
265-
NSLog(@"Selected idx=%ld", selected);
266263
if (selected >= 0 && section == 0)
267264
{
268265
[self.coreDataIntrospection loadEntityDataAtIndex:selected];
@@ -272,7 +269,8 @@ - (void)onEntitySelected {
272269
[self addTableColumnWithIdentifier:name];
273270
}
274271

275-
[self.coreDataIntrospection loadEntityDataAtIndex:selected];
272+
// TODO - why was this called twice?
273+
//[self.coreDataIntrospection loadEntityDataAtIndex:selected];
276274
[self.coreDataIntrospection updateCoreDataHistory:[self.coreDataIntrospection entityAtIndex:selected] predicate:nil objectType:MFLObjectTypeEntity];
277275

278276
} else if (selected >= 0 && section == 1)
@@ -291,6 +289,7 @@ - (void)onEntitySelected {
291289
[self.entityContentTable reloadData];
292290

293291
[self enableDisableHistorySegmentedControls];
292+
NSLog(@"Selected %@, selected=%d, section:%d, %@ms", selectedNode.title, (int)selected, (int)section, [MFLUtils duration:startTime]);
294293
}
295294
}
296295

@@ -353,24 +352,9 @@ - (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
353352

354353
- (id)getValueObjFromDataRows:(NSTableView *)tableView :(NSInteger)row :(NSTableColumn *)tableColumn
355354
{
356-
NSArray* dataRow;
357355
NSInteger normalizedRow = [self sortOrderedRow:tableView row:row];
358-
359-
id valueObj = nil;
360-
@try
361-
{
362-
dataRow = [self.coreDataIntrospection getDataAtRow:normalizedRow];
363-
364-
valueObj = [dataRow valueForKey:[tableColumn identifier]];
365-
}
366-
@catch (NSException *exception)
367-
{
368-
// Not sure what is going on here. This happens sometimes. We need to sort this one out...
369-
NSLog(@"Row=%ld, normalizedRow=%ld, numRows=%ld, entityCount=%ld", row, normalizedRow, [self.entityContentTable numberOfRows], [self.coreDataIntrospection entityDataCount]);
370-
NSLog(@"Row[%ld]: Caught Exception: %@ [%@], %@",row, exception, tableColumn, dataRow);
371-
valueObj = nil;
372-
}
373-
356+
NSArray *dataRow = [self.coreDataIntrospection getDataAtRow:(NSUInteger)normalizedRow];
357+
id valueObj = [dataRow valueForKey:[tableColumn identifier]];
374358
return valueObj;
375359
}
376360

@@ -384,6 +368,10 @@ - (NSInteger) sortOrderedRow:(NSTableView *)tableView row:(NSInteger) row {
384368
return normalizedRow;
385369
}
386370

371+
- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row {
372+
return 20;
373+
}
374+
387375
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
388376
{
389377
if (tableView == [self dataSourceList])
@@ -399,11 +387,9 @@ - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn
399387

400388
return entityCell;
401389
}
402-
403-
if (tableView == [self entityContentTable])
390+
else if (tableView == [self entityContentTable])
404391
{
405392
id valueObj = [self getValueObjFromDataRows:tableView :row :tableColumn];
406-
407393
if (valueObj == nil)
408394
{
409395
MFLTextTableCellView* textCell = [MFLCellBuilder nullCell:tableView owner:self];
@@ -414,6 +400,7 @@ - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn
414400
NSString* cellText = [NSString stringWithFormat:@"%@", valueObj];
415401
if ([cellText hasPrefix:@"http"]) {
416402
MFLButtonTableViewCell* buttonCell = [tableView makeViewWithIdentifier:MFL_BUTTON_CELL owner:self];
403+
buttonCell.wantsLayer = YES;
417404
[[buttonCell infoField] setTextColor:[NSColor blackColor]];
418405
[[buttonCell infoField] setStringValue: cellText];
419406
return buttonCell;
@@ -428,24 +415,23 @@ - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn
428415
NSURL* url = (NSURL*) valueObj;
429416
NSString* cellText = [NSString stringWithFormat:@"%@", [url absoluteString]];
430417
MFLButtonTableViewCell* buttonCell = [tableView makeViewWithIdentifier:MFL_BUTTON_CELL owner:self];
418+
buttonCell.wantsLayer = YES;
431419
[[buttonCell infoField] setTextColor:[NSColor blackColor]];
432420
[[buttonCell infoField] setStringValue: cellText];
433421
return buttonCell;
434-
// MFLTextTableCellView* textCell = [MFLCellBuilder textCellWithString:tableView textToSet:cellText owner:self];
435-
// return textCell;
436422
}
437423
else if ([valueObj isKindOfClass:[NSDate class]])
438424
{
439425
[self setupDateFormatter];
440426
NSString *cellText = [self.dateFormatter stringFromDate:valueObj];
441427
MFLTextTableCellView* textCell = [MFLCellBuilder textCellWithString:tableView textToSet:cellText owner:self];
442-
443428
return textCell;
444429
}
445430
else if ([valueObj isKindOfClass:[NSData class]])
446431
{
447432
NSString* cellText = [NSString stringWithFormat:@"%ld", [valueObj length]];
448433
MFLTextTableCellView* textCell = [MFLCellBuilder numberCellWithString:tableView textToSet:cellText owner: self];
434+
textCell.wantsLayer = YES;
449435
return textCell;
450436
}
451437
else if ([valueObj isKindOfClass:[NSNumber class]])
@@ -460,14 +446,14 @@ - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn
460446
cellText = [NSString stringWithFormat:@"%@", valueObj];
461447
}
462448
MFLTextTableCellView* textCell = [MFLCellBuilder numberCellWithString:tableView textToSet:cellText owner:self];
449+
textCell.wantsLayer = YES;
463450
return textCell;
464451
}
465-
466-
// Button Cells
467452
else if ([valueObj isKindOfClass:[NSManagedObject class]])
468453
{
469454
NSString* cellText = [NSString stringWithFormat:@"%@", [[valueObj entity] name]];
470455
MFLButtonTableViewCell* buttonCell = [MFLCellBuilder objectCellWithString:tableView textToSet:cellText owner:self];
456+
buttonCell.wantsLayer = YES;
471457
return buttonCell;
472458
}
473459
else if ([valueObj isKindOfClass:[NSSet class]])
@@ -480,6 +466,7 @@ - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn
480466
NSString *cellText = [NSString stringWithFormat:@"%@[%ld]", [[object entity] name], [valueObj count]];
481467

482468
MFLButtonTableViewCell* buttonCell = [tableView makeViewWithIdentifier:MFL_BUTTON_CELL owner:self];
469+
buttonCell.wantsLayer = YES;
483470
[[buttonCell infoField] setAlignment:NSRightTextAlignment];
484471
[[buttonCell infoField] setTextColor:[NSColor blackColor]];
485472
[[buttonCell infoField] setStringValue: cellText];
@@ -506,13 +493,15 @@ - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn
506493
NSString *cellText = [NSString stringWithFormat:@"%@[%ld]", [[object entity] name], [valueObj count]];
507494

508495
MFLButtonTableViewCell* buttonCell = [tableView makeViewWithIdentifier:MFL_BUTTON_CELL owner:self];
496+
buttonCell.wantsLayer = YES;
509497
[[buttonCell infoField] setAlignment:NSRightTextAlignment];
510498
[[buttonCell infoField] setTextColor:[NSColor blackColor]];
511499
[[buttonCell infoField] setStringValue: cellText];
512500
return buttonCell;
513501
} else {
514502
NSString *cellText = [NSString stringWithFormat:@"%@", valueObj];
515503
MFLTextTableCellView* textCell = [MFLCellBuilder textCellWithString:tableView textToSet:cellText owner:self];
504+
textCell.wantsLayer = YES;
516505
return textCell;
517506
}
518507
}
@@ -524,7 +513,6 @@ - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn
524513
}
525514
else if ([valueObj isKindOfClass:[NSOrderedSet class]])
526515
{
527-
528516
if ([valueObj count] > 0)
529517
{
530518
id obj = [valueObj firstObject];
@@ -533,13 +521,15 @@ - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn
533521
NSString *cellText = [NSString stringWithFormat:@"%@[%ld]", [[object entity] name], [valueObj count]];
534522

535523
MFLButtonTableViewCell* buttonCell = [tableView makeViewWithIdentifier:MFL_BUTTON_CELL owner:self];
524+
buttonCell.wantsLayer = YES;
536525
[[buttonCell infoField] setAlignment:NSRightTextAlignment];
537526
[[buttonCell infoField] setTextColor:[NSColor blackColor]];
538527
[[buttonCell infoField] setStringValue: cellText];
539528
return buttonCell;
540529
} else {
541530
NSString *cellText = [NSString stringWithFormat:@"%@", valueObj];
542531
MFLTextTableCellView* textCell = [MFLCellBuilder textCellWithString:tableView textToSet:cellText owner:self];
532+
textCell.wantsLayer = YES;
543533
return textCell;
544534
}
545535
}
@@ -553,23 +543,22 @@ - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn
553543
{
554544
NSString* cellText = [NSString stringWithFormat:@"%@", @"NSDictionary Data"];
555545
TransformableDataTableViewCell* buttonCell = [tableView makeViewWithIdentifier:MFL_TRANSFORM_CELL owner:self];
546+
buttonCell.wantsLayer = YES;
556547
[[buttonCell infoField] setAlignment:NSRightTextAlignment];
557548
[[buttonCell infoField] setTextColor:[NSColor blackColor]];
558549
[[buttonCell infoField] setStringValue: cellText];
559-
560550
return buttonCell;
561551
}
562552
// Unhandled types of content
563553
else
564554
{
565-
NSLog(@"is Other");
566-
555+
NSLog(@"Unknown content: %@", valueObj);
567556
NSString* cellText = [NSString stringWithFormat:@"??? %@ ???", [valueObj class]];
568557
TransformableDataTableViewCell* buttonCell = [tableView makeViewWithIdentifier:MFL_TRANSFORM_CELL owner:self];
558+
buttonCell.wantsLayer = YES;
569559
[[buttonCell infoField] setAlignment:NSRightTextAlignment];
570560
[[buttonCell infoField] setTextColor:[NSColor blackColor]];
571561
[[buttonCell infoField] setStringValue: cellText];
572-
573562
return buttonCell;
574563
}
575564
}

0 commit comments

Comments
 (0)