Discussion:
Need a direction. App crash in CoreData while loading a window's nib
Motti Shneor
2018-11-03 20:47:03 UTC
Permalink
Hi. This is Objective-C, NSDocument based (CoreData document) based application, running long time in production, that suddenly started crashing for me.

I have a main window (naster/detail) presents a relatively large database. Each line when double-clicked, opens a secondary window to show another table of data - related to the selection in the main window.

e.g.

ID Location Researcher Type Observations
1045 A Sara PhytoPlankton 30
1046 B Merav PhytoPlankton 223
1047 A Diti PhytoPlankton 3219
1056 D Diti PhytoPlankton 2890

Double clicking the line with ID 1045 or 1046, will open a table showing 30/223 “observations” - OK. However, double-clicking lines 1047 or 1056 - will hang a little - then crash with “Bad Access” which I strongly suspect to be something else.

My stack trace at the crash is HUGE (about 48300 depth!) It starts reasonably like this:

#48271 0x00007fff38f40064 in -[NSController _notifyObserversForKeyPath:change:] ()
#48272 0x00007fff38f8b47c in -[NSArrayController didChangeValuesForArrangedKeys:objectKeys:indexKeys:] ()
#48273 0x00007fff38f8cf3f in -[NSArrayController setContent:] ()
#48274 0x00007fff38f8c93e in -[NSArrayDetailBinder _refreshDetailContentInBackground:] ()
#48275 0x00007fff38ddc8db in -[NSObject(NSKeyValueBindingCreation) bind:toObject:withKeyPath:options:] ()
#48276 0x00007fff38d58719 in -[NSIBObjectData nibInstantiateWithOwner:options:topLevelObjects:] ()
#48277 0x00007fff38d4f991 in loadNib ()
#48278 0x00007fff38d4eeb5 in +[NSBundle(NSNibLoading) _loadNibFile:nameTable:options:withZone:ownerBundle:] ()
#48279 0x00007fff38f84aba in +[NSBundle(NSNibLoadingInternal) _loadNibFile:externalNameTable:options:withZone:] ()
#48280 0x00007fff38f84893 in -[NSWindowController loadWindow] ()
#48281 0x00007fff38d97cf5 in -[NSWindowController window] ()
#48282 0x000000010002bdb7 in -[PMXDocumentWindowController showMeasurements:] at /Users/motti/Client Projects/IOLR/PlanktoMetrix II (Cocoa)/planktometrix-ii/PlanktoMetrix-II/PlanktoMetrix-II/PMXDocumentWindowController.m:867
#48283 0x00007fff39520a43 in -[NSApplication(NSResponder) sendAction:to:from:] ()
#48284 0x00007fff38fc653f in -[NSControl sendAction:to:] ()
#48285 0x00007fff3903a069 in -[NSTableView _sendAction:to:row:column:] ()
#48286 0x00007fff390384a8 in -[NSTableView mouseDown:] ()
#48287 0x00007fff396bfd6d in -[NSWindow(NSEventRouting) _handleMouseDownEvent:isDelayedEvent:] ()
#48288 0x00007fff396bc9c4 in -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] ()
#48289 0x00007fff396bbc70 in -[NSWindow(NSEventRouting) sendEvent:] ()
#48290 0x00007fff3951d236 in -[NSApplication(NSEvent) sendEvent:] ()
#48291 0x00007fff38d7d8b5 in -[NSApplication run] ()
#48292 0x00007fff38d4ca72 in NSApplicationMain ()
#48293 0x0000000100001a72 in main at /Users/motti/Client Projects/IOLR/PlanktoMetrix II (Cocoa)/planktometrix-ii/PlanktoMetrix-II/PlanktoMetrix-II/main.m:13
#48294 0x00007fff63711015 in start ()
#48295 0x00007fff63711015 in start ()

But then continues with an infinite nesting of cocoa-binding related ‘blocks’, that in the end - (topmost calls) crash on NSSQLitConnection connect call - like this:

#0 0x00007fff3b342a8d in -[NSSQLiteConnection connect] ()
#1 0x00007fff3b525c97 in -[NSSQLStoreRequestContext executeRequestUsingConnection:] ()
#2 0x00007fff3b534f5b in __52-[NSSQLDefaultConnectionManager handleStoreRequest:]_block_invoke ()
#3 0x00000001004e9d8f in _dispatch_client_callout ()
#4 0x00000001004fe8bf in _dispatch_queue_barrier_sync_invoke_and_complete ()
#5 0x00007fff3b534e44 in -[NSSQLDefaultConnectionManager handleStoreRequest:] ()
#6 0x00007fff3b4755e1 in -[NSSQLCoreDispatchManager routeStoreRequest:] ()
#7 0x00007fff3b43ce55 in -[NSSQLCore dispatchRequest:withRetries:] ()
#8 0x00007fff3b3669be in -[NSSQLCore newValuesForObjectWithID:withContext:error:] ()
#9 0x00007fff3b41a4c4 in __95-[NSPersistentStoreCoordinator(_NSInternalMethods) newValuesForObjectWithID:withContext:error:]_block_invoke ()
#10 0x00007fff3b40e9e7 in -[NSPersistentStoreCoordinator _routeLightweightBlock:toStore:] ()
#11 0x00007fff3b3667ae in -[NSPersistentStoreCoordinator(_NSInternalMethods) newValuesForObjectWithID:withContext:error:] ()
#12 0x00007fff3b3c99fd in __92-[NSManagedObjectContext(_NestedContextSupport) newValuesForObjectWithID:withContext:error:]_block_invoke ()
#13 0x00007fff3b38ee62 in internalBlockToNSManagedObjectContextPerform ()
#14 0x00000001004e9d8f in _dispatch_client_callout ()
#15 0x00000001004fe8bf in _dispatch_queue_barrier_sync_invoke_and_complete ()
#16 0x00007fff3b38ed6c in _perform ()
#17 0x00007fff3b38f988 in -[NSManagedObjectContext(_NestedContextSupport) newValuesForObjectWithID:withContext:error:] ()
#18 0x00007fff3b365eb2 in _PFFaultHandlerLookupRow ()
#19 0x00007fff3b365700 in _PF_FulfillDeferredFault ()
#20 0x00007fff3b365517 in _pvfk_header ()
#21 0x00007fff3b365485 in _sharedIMPL_pvfk_core ()
#22 0x00007fff3b396cdd in _PF_Handler_Public_GetProperty ()
#23 0x00007fff3da38636 in -[NSArray(NSKeyValueCoding) _unionOfObjectsForKeyPath:] ()
#24 0x00007fff3da3880d in -[NSArray(NSKeyValueCoding) _distinctUnionOfObjectsForKeyPath:] ()
#25 0x00007fff3d90ad3f in -[NSArray(NSKeyValueCoding) valueForKeyPath:] ()
#26 0x00007fff3d90ab7d in -[NSObject(NSKeyValueCoding) valueForKeyPath:] ()
#27 0x00007fff38de44ab in -[NSBinder valueForBinding:resolveMarkersToPlaceholders:] ()
#28 0x00007fff38f8c639 in -[NSArrayDetailBinder _refreshDetailContentInBackground:] ()
#29 0x00007fff3d9069c9 in NSKeyValueNotifyObserver ()

Obviously, there is something chaining far-too-many objects here - and I would never guess that normal NSTableColumn bindings are all done nested… still this app runs OK with the same database for customers, and It didn’t crash there before.

I wouldn’t even think NSTable should attempt to load ALL the lines despite the fact that only few of them appear in the window initially.

Since EVERYTHING in the stack (except for #48282 which is my action to open that window) trace (except #48282 which is my action to open that window) is Cocoa SDK code - I don’t know where to start looking for the culprit.

I suspect also, that if I could “untie” something here - my app will also enjoy better responsiveness.

The window I’m trying to present has a single, cell-based NSTable, with 10 columns, each bound to the same CoreData entity via ArrayController. There are also 2 custom views in that window’s nib - used within NSAlert dialogs if user elects to use those.

Most of the bindings are naive and simple - one column is showing a popup-button whose bindings are little more complicated - but that’s it.

Can anyone suggest a way to start bisecting the issue or an idea where to look for?

Many thanks.
Motti.

_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narki
Richard Charles
2018-11-04 02:18:00 UTC
Permalink
Post by Motti Shneor
Can anyone suggest a way to start bisecting the issue or an idea where to look for?
You may have bad or corrupted data in your core data persistent store. Save the file out as an xml and see if you find anything suspicious.

You could also open the sqlite file with the Base.app by Menial and see what happens and take a look at the data.

--Richard Charles

_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.narkive.net
Motti Shneor
2018-11-04 07:42:20 UTC
Permalink
Thanks Richard.

The data is OK. Not corrupt. I can import and export it to .csv, and I do run several sanity test (heavy calculations based on that data pass OK and provide expected results). Most important - the production build of the software (built half year ago), opens the same database and doesn't crash on the same data. It IS hanging about a second when opening those items but “survives” it.

I cannot save it as XML easily - it is a rather big database about 500MB with tens of millions of entities, in 20 interrelated tables (LOTS of complicated relations). Most of the logic of this software is in its schema.

More things I’ve done:
1. I tested, double-clicking different items - it seems quite consistent. Anything over ~2500 items to show in that window will crash while smaller relation sets “survive”

2. I put a symbolic breakpoint on -[NSSQLiteConnection connect] and double-clicked an item that opens without crashing (about 1000 related items to show). The behaviour is weird. I hit the breakpoint time and again, with a stack that looks exactly like the one I described - except that in the first stop there is only ONE iteration of that binding thing, next break I’ll see 2 nested iterations of the binding calls, then 3, 4, 5 — and the stack gets longer and longer each hit. I did not survive to free it a 1000 times, but I think the rule is - it will iterate 1000 times, each time going deeper, until it either “survives” to open the window, or crashes for (what I think of as) stack overflow.

3. I tried to build with Xcode 9.4.1 (MacOS SDK 10.13) then with Xcode 10 (MacOS SDK 10.14) - same thing. I only have my MacOS 10.13 to try running on. I cannot run the original Xcode (8.x) with which the production version was built. It won’t run on my OS.

I just do not know how to go about resolving this.

Another idea I had — I’m using AutoLayout in the .xib file. Maybe — for pre-caculating the “needed” space for some table column, it needs to know in advance the widths of all texts it should ever display there, hence it is forced to scan the whole data via some bindings before it can finally show the table?

If so - this cannot (of course) survive longer tables. Still the question why older builds do survive.

Motti Shneor
Post by Richard Charles
Post by Motti Shneor
Can anyone suggest a way to start bisecting the issue or an idea where to look for?
You may have bad or corrupted data in your core data persistent store. Save the file out as an xml and see if you find anything suspicious.
You could also open the sqlite file with the Base.app by Menial and see what happens and take a look at the data.
--Richard Charles
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This em
Richard Charles
2018-11-04 15:25:38 UTC
Permalink
Post by Motti Shneor
I just do not know how to go about resolving this.
Here is another idea. Remove your bindings one at a time. Perhaps it is just one binding that is causing the problem and then you can perhaps track it from there. It looks like this may be some kind of KVO problem.

--Richard Charles

_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.narkive.net
Hunter Hillegas
2018-11-04 15:59:43 UTC
Permalink
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.narkive.net
Hunter Hillegas
2018-11-04 16:00:37 UTC
Permalink
Post by Motti Shneor
3. I tried to build with Xcode 9.4.1 (MacOS SDK 10.13) then with Xcode 10 (MacOS SDK 10.14) - same thing. I only have my MacOS 10.13 to try running on. I cannot run the original Xcode (8.x) with which the production version was built. It won’t run on my OS.
Apple does provide older versions of macOS that you can download and run in something like vmWare or Parallels if you want to try running Xcode 8 - it would be interesting to see what happens there. Looks like Xcode 8 will run on Sierra which you may be able to get via this link: https://itunes.apple.com/gb/app/macos-sierra/id1127487414?mt=12

AppKit and other libraries do often behave slightly differently based on the version they are built and run against, to maintain compatibility. So it’s possible that a build from Xcode 8 would hit slightly different code paths in the frameworks than Xcode 9 or 10.
Post by Motti Shneor
Another idea I had — I’m using AutoLayout in the .xib file. Maybe — for pre-caculating the “needed” space for some table column, it needs to know in advance the widths of all texts it should ever display there, hence it is forced to scan the whole data via some bindings before it can finally show the table?
I’m much more fluent in UIKit than AppKit but I’d be surprised if this was the case - would make Core Data faults, one of the best features for dealing with large data sets, basically worthless when used with NSTableView.

That said, you could try profiling this in Instruments to see what it’s doing in that period of time right before it crashes when it’s burning CPU.
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.n
Dave Fernandes
2018-11-04 18:15:23 UTC
Permalink
Does your code modify anything in the persistent store during loading (NSManagedObjectContextDidChangeNotification)? Maybe it is rounding some values for display? This might cause infinite recursion with bindings.
Post by Motti Shneor
Thanks Richard.
The data is OK. Not corrupt. I can import and export it to .csv, and I do run several sanity test (heavy calculations based on that data pass OK and provide expected results). Most important - the production build of the software (built half year ago), opens the same database and doesn't crash on the same data. It IS hanging about a second when opening those items but “survives” it.
I cannot save it as XML easily - it is a rather big database about 500MB with tens of millions of entities, in 20 interrelated tables (LOTS of complicated relations). Most of the logic of this software is in its schema.
1. I tested, double-clicking different items - it seems quite consistent. Anything over ~2500 items to show in that window will crash while smaller relation sets “survive”
2. I put a symbolic breakpoint on -[NSSQLiteConnection connect] and double-clicked an item that opens without crashing (about 1000 related items to show). The behaviour is weird. I hit the breakpoint time and again, with a stack that looks exactly like the one I described - except that in the first stop there is only ONE iteration of that binding thing, next break I’ll see 2 nested iterations of the binding calls, then 3, 4, 5 — and the stack gets longer and longer each hit. I did not survive to free it a 1000 times, but I think the rule is - it will iterate 1000 times, each time going deeper, until it either “survives” to open the window, or crashes for (what I think of as) stack overflow.
3. I tried to build with Xcode 9.4.1 (MacOS SDK 10.13) then with Xcode 10 (MacOS SDK 10.14) - same thing. I only have my MacOS 10.13 to try running on. I cannot run the original Xcode (8.x) with which the production version was built. It won’t run on my OS.
I just do not know how to go about resolving this.
Another idea I had — I’m using AutoLayout in the .xib file. Maybe — for pre-caculating the “needed” space for some table column, it needs to know in advance the widths of all texts it should ever display there, hence it is forced to scan the whole data via some bindings before it can finally show the table?
If so - this cannot (of course) survive longer tables. Still the question why older builds do survive.
Motti Shneor
Post by Richard Charles
Post by Motti Shneor
Can anyone suggest a way to start bisecting the issue or an idea where to look for?
You may have bad or corrupted data in your core data persistent store. Save the file out as an xml and see if you find anything suspicious.
You could also open the sqlite file with the Base.app by Menial and see what happens and take a look at the data.
--Richard Charles
_______________________________________________
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
https://lists.apple.com/mailman/options/cocoa-dev/dave.fernandes%40utoronto.ca
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.n
Dave Fernandes
2018-11-04 19:41:08 UTC
Permalink
Hi Dave and thanks for the reply.
As for modifying the persistent store - I guess I don’t because the database-document does not become “dirty”. If I double click one of the “sample” entities that can be open - and the window is shown as expected, then I close the document - there are no autosaves or changes recorded. The modification time of the persistent store does not change.
However - you’re right to point at NSManagedObjectContextDidChangeNotification — how could I get it to pop?
Set up an observer for that notification for your MOC and set a breakpoint in that observer.
3 of my NSTableColumn do have a formatter for the number presented - but why should this affect the context, The columns are not “editable” in-place.
Just trying to narrow this down without assuming too much.
I will attempt to delete these columns and try again…
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email
Motti Shneor
2018-11-04 22:25:36 UTC
Permalink
Well, thanks Dave, Hunter, Richard and the rest.

I followed each of your suggestions, and I finally found the culprit.

A single binding, rather a nifty one, which I don’t know how to do better — Maybe you can help. Removing this binding (alas losing functionality) window opens instantly, regardless of the number of items.

First off — the issue is NOT in any of the table columns. They do have complicated bindings, but all work fast and fine.

In the .xib there is also a custom view, only used as an accessory view to an NSAlert dialog, when user choses to perform special editing on the items displayed. (Kind of search-and-replace action).

In that view, there’s a popup button, populated by binding to a (quite special) array controller. That array controller’s content-array has the binding that breaks window loading.

I’ll try to explain:

This NSTable in the window displays a list of all “Measurement” entities related to a specific “Sample” (the “representedObject” of the File’s owner).
For that I have a “Measurements Array Controller” in “Entity” mode, whose content array is bound to File’s Owner’s “representedObject.measurements” relation. All table columns are bound to that array controller.

Now each Measurement is connected via to-one relation to a “Species” entity.

In my custom view, I wish to populate a popup button with all the Species entities which appear in the displayed Measurements.

For that, I created the “Used Species Array Controller” whose section in the .xib appears below:


<arrayController mode="entity" entityName="Species" editable="NO" automaticallyPreparesContent="YES" preservesSelection="NO" selectsInsertedObjects="NO" avoidsEmptySelection="NO" clearsFilterPredicateOnInsertion="NO" automaticallyRearrangesObjects="YES" id="syR-1c-VXy" userLabel="Used Species Array Controller">
<connections>
BAD: <binding destination="4l9-1K-ojl" name="contentArray" keyPath="***@distinctUnionOfObjects.species" id="TQk-n5-RYc”/>
<binding destination="-2" name="managedObjectContext" keyPath="representedObject.managedObjectContext" id="Vqg-dg-DdM"/>
<binding destination="xYM-bl-Wzq" name="sortDescriptors" keyPath="sortDescriptors" id="3uW-GQ-bKN"/>
</connections>
</arrayController>


The “Bad” binding destination, is the Measurements Array Controller’s “arrangedObjects”, and the model keyPath is “@distinctUnionOfObjects.species”

Effectively, when calculated, this “collects” all the species from all displayed measurements, removing any duplicates. Nifty, isn’t it?

I can’t provide the list statically, in advance, because the user is free to replace the species of displayed measurements - and although this is rather “heavy” binding - I can’t see anything “recursive” about it, or otherwise iteratively-dependent. I would guess this ArrayController should “Prepare” its content array once - and forget about it, until time any of the Measurements (arrangedObjects) mutate.

I know this isn’t easy to grasp… but any idea for how to improve this will be greatly appreciated.

Thanks again!

Motti Shneor
---
Ceterum censeo Microsoftinem delendam esse
Post by Dave Fernandes
Hi Dave and thanks for the reply.
As for modifying the persistent store - I guess I don’t because the database-document does not become “dirty”. If I double click one of the “sample” entities that can be open - and the window is shown as expected, then I close the document - there are no autosaves or changes recorded. The modification time of the persistent store does not change.
However - you’re right to point at NSManagedObjectContextDidChangeNotification — how could I get it to pop?
Set up an observer for that notification for your MOC and set a breakpoint in that observer.
3 of my NSTableColumn do have a formatter for the number presented - but why should this affect the context, The columns are not “editable” in-place.
Just trying to narrow this down without assuming too much.
I will attempt to delete these columns and try again…
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This emai
Sandor Szatmari
2018-11-04 23:04:16 UTC
Permalink
If you can, can you establish the binding programmatically after launch? If so, does the program crash once the bindings are re-established? … considering if it is a launch issue or more systematic?

Sandor
Post by Motti Shneor
Well, thanks Dave, Hunter, Richard and the rest.
I followed each of your suggestions, and I finally found the culprit.
A single binding, rather a nifty one, which I don’t know how to do better — Maybe you can help. Removing this binding (alas losing functionality) window opens instantly, regardless of the number of items.
First off — the issue is NOT in any of the table columns. They do have complicated bindings, but all work fast and fine.
In the .xib there is also a custom view, only used as an accessory view to an NSAlert dialog, when user choses to perform special editing on the items displayed. (Kind of search-and-replace action).
In that view, there’s a popup button, populated by binding to a (quite special) array controller. That array controller’s content-array has the binding that breaks window loading.
This NSTable in the window displays a list of all “Measurement” entities related to a specific “Sample” (the “representedObject” of the File’s owner).
For that I have a “Measurements Array Controller” in “Entity” mode, whose content array is bound to File’s Owner’s “representedObject.measurements” relation. All table columns are bound to that array controller.
Now each Measurement is connected via to-one relation to a “Species” entity.
In my custom view, I wish to populate a popup button with all the Species entities which appear in the displayed Measurements.
<arrayController mode="entity" entityName="Species" editable="NO" automaticallyPreparesContent="YES" preservesSelection="NO" selectsInsertedObjects="NO" avoidsEmptySelection="NO" clearsFilterPredicateOnInsertion="NO" automaticallyRearrangesObjects="YES" id="syR-1c-VXy" userLabel="Used Species Array Controller">
<connections>
<binding destination="-2" name="managedObjectContext" keyPath="representedObject.managedObjectContext" id="Vqg-dg-DdM"/>
<binding destination="xYM-bl-Wzq" name="sortDescriptors" keyPath="sortDescriptors" id="3uW-GQ-bKN"/>
</connections>
</arrayController>
Effectively, when calculated, this “collects” all the species from all displayed measurements, removing any duplicates. Nifty, isn’t it?
I can’t provide the list statically, in advance, because the user is free to replace the species of displayed measurements - and although this is rather “heavy” binding - I can’t see anything “recursive” about it, or otherwise iteratively-dependent. I would guess this ArrayController should “Prepare” its content array once - and forget about it, until time any of the Measurements (arrangedObjects) mutate.
I know this isn’t easy to grasp… but any idea for how to improve this will be greatly appreciated.
Thanks again!
Motti Shneor
---
Ceterum censeo Microsoftinem delendam esse
Post by Dave Fernandes
Hi Dave and thanks for the reply.
As for modifying the persistent store - I guess I don’t because the database-document does not become “dirty”. If I double click one of the “sample” entities that can be open - and the window is shown as expected, then I close the document - there are no autosaves or changes recorded. The modification time of the persistent store does not change.
However - you’re right to point at NSManagedObjectContextDidChangeNotification — how could I get it to pop?
Set up an observer for that notification for your MOC and set a breakpoint in that observer.
3 of my NSTableColumn do have a formatter for the number presented - but why should this affect the context, The columns are not “editable” in-place.
Just trying to narrow this down without assuming too much.
I will attempt to delete these columns and try again…
_______________________________________________
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
https://lists.apple.com/mailman/options/cocoa-dev/admin.szatmari.net%40gmail.com
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.na
Motti Shneor
2018-11-04 23:48:08 UTC
Permalink
Well - 2AM and I finally resolved it. I also think I understand why the strange recursion occurs

This double-layer binding of content-array of one NSArrayController to the arrangedObjects of another NSArrayController (who’s bound to an ordered relation of…. ) made loading to occur like this.

1 “Measurements” array controller loads 1 entity. It rearranges its objects. This triggers:
2. “Used Species” array controller to reload and rearrange its content array. This puts to use the computational key path @distinctUnionOfObjects.species that scans all the “Measurements” arrangedObject.
3, Measurements array controllers loads another entity, now having two - and rearranges its objects again. Triggers
4. “Used Species” array controller to reload and rearrange its content array.

And so on.

What I did, is to add a calculated property to the File’s Owner (the WindowController) providing this needed ContentArray in one shot:

@property (readonly, nonatomic) NSArray *speciesInUse;


-(NSArray *) speciesInUse {
return [self.representedObject.measurements.array valueForKeyPath:@"@distinctUnionOfObjects.species"];
}

Now my “Used Species Array Controller” binds against FileOwner’s “speciesInUse” property - and the dependency is broken.

All is well, goodnight everyone, and thanks a million for all the help.
Post by Sandor Szatmari
If you can, can you establish the binding programmatically after launch? If so, does the program crash once the bindings are re-established? … considering if it is a launch issue or more systematic?
Sandor
Post by Motti Shneor
Well, thanks Dave, Hunter, Richard and the rest.
I followed each of your suggestions, and I finally found the culprit.
A single binding, rather a nifty one, which I don’t know how to do better — Maybe you can help. Removing this binding (alas losing functionality) window opens instantly, regardless of the number of items.
First off — the issue is NOT in any of the table columns. They do have complicated bindings, but all work fast and fine.
In the .xib there is also a custom view, only used as an accessory view to an NSAlert dialog, when user choses to perform special editing on the items displayed. (Kind of search-and-replace action).
In that view, there’s a popup button, populated by binding to a (quite special) array controller. That array controller’s content-array has the binding that breaks window loading.
This NSTable in the window displays a list of all “Measurement” entities related to a specific “Sample” (the “representedObject” of the File’s owner).
For that I have a “Measurements Array Controller” in “Entity” mode, whose content array is bound to File’s Owner’s “representedObject.measurements” relation. All table columns are bound to that array controller.
Now each Measurement is connected via to-one relation to a “Species” entity.
In my custom view, I wish to populate a popup button with all the Species entities which appear in the displayed Measurements.
<arrayController mode="entity" entityName="Species" editable="NO" automaticallyPreparesContent="YES" preservesSelection="NO" selectsInsertedObjects="NO" avoidsEmptySelection="NO" clearsFilterPredicateOnInsertion="NO" automaticallyRearrangesObjects="YES" id="syR-1c-VXy" userLabel="Used Species Array Controller">
<connections>
<binding destination="-2" name="managedObjectContext" keyPath="representedObject.managedObjectContext" id="Vqg-dg-DdM"/>
<binding destination="xYM-bl-Wzq" name="sortDescriptors" keyPath="sortDescriptors" id="3uW-GQ-bKN"/>
</connections>
</arrayController>
Effectively, when calculated, this “collects” all the species from all displayed measurements, removing any duplicates. Nifty, isn’t it?
I can’t provide the list statically, in advance, because the user is free to replace the species of displayed measurements - and although this is rather “heavy” binding - I can’t see anything “recursive” about it, or otherwise iteratively-dependent. I would guess this ArrayController should “Prepare” its content array once - and forget about it, until time any of the Measurements (arrangedObjects) mutate.
I know this isn’t easy to grasp… but any idea for how to improve this will be greatly appreciated.
Thanks again!
Motti Shneor
---
Ceterum censeo Microsoftinem delendam esse
Post by Dave Fernandes
Hi Dave and thanks for the reply.
As for modifying the persistent store - I guess I don’t because the database-document does not become “dirty”. If I double click one of the “sample” entities that can be open - and the window is shown as expected, then I close the document - there are no autosaves or changes recorded. The modification time of the persistent store does not change.
However - you’re right to point at NSManagedObjectContextDidChangeNotification — how could I get it to pop?
Set up an observer for that notification for your MOC and set a breakpoint in that observer.
3 of my NSTableColumn do have a formatter for the number presented - but why should this affect the context, The columns are not “editable” in-place.
Just trying to narrow this down without assuming too much.
I will attempt to delete these columns and try again…
_______________________________________________
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
https://lists.apple.com/mailman/options/cocoa-dev/admin.szatmari.net%40gmail.com
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.n

Loading...