NSArrayController vs. fetch

  • I'm displaying a list of entities in a tableview. I have an outlet to
    their NSArrayController  in my document. If I want to perform some
    operations on them which is the best choice for retrieving the
    associated NSArray between

    array=[myArrayController arrangedObjects];

    and the execution of a fetch request as:

    [request setEntity:[NSEntityDescription entityForName:@"myEntity"
    inManagedObjectContext:moc]];
    array=[moc executeFetchRequest:request error:error];

    I think the second one is surely updated since synchronizes with the
    persistent store, while the first might lead to some problems.
    Again, is the first approach considered a poor or even  wrong
    implementation ? Which is the fastest, anyway ?
    Thank you,
    Matteo Rossi
  • On Oct 6, 2006, at 4:22 AM, Matteo Rossi wrote:

    > I'm displaying a list of entities in a tableview. I have an outlet
    > to their NSArrayController  in my document. If I want to perform
    > some operations on them which is the best choice for retrieving the
    > associated NSArray between
    > array=[myArrayController arrangedObjects];
    > and the execution of a fetch request as:
    > [request setEntity:[NSEntityDescription entityForName:@"myEntity"
    > inManagedObjectContext:moc]];
    > array=[moc executeFetchRequest:request error:error];
    > I think the second one is surely updated since synchronizes with the
    > persistent store, while the first might lead to some problems.
    > Again, is the first approach considered a poor or even  wrong
    > implementation ? Which is the fastest, anyway ?
    >
    If you want to perform an operation on the content of a table view
    provided by an array controller, then use -arrangedObjects -- that's
    what it's there for...  If you perform a fetch, then you may get back
    a different result set (notably if the content of the array controller
    is filtered) and the ordering may be different (in some situations
    this might be important to you).  Moreover, the fetch incurs a round
    trip to the persistent store, whereas the value of arrangedObjects may
    be cached.

    mmalc
  • > If you want to perform an operation on the content of a table view
    > provided by an array controller, then use -arrangedObjects --
    > that's what it's there for...

    Well, indeed, I don't want to perform an operation on a tableview, I
    use arrangedObjects to retrieve all entities of a certain kind and
    draw them on screen (they are lines); my primary goal is an
    ***UPDATED*** array of lines; the second one is a fast response. In
    other words I must be sure that all  entities are correctly
    synchronized to the ones I creates/removed/modified.  Is it correct
    that they are ONLY IF the tableview is displayed ? If I hide my
    tableview (or have no tableview at all) and add an entity
    programmatically, I think I'll have to run a fetch to retrieve all
    entities including the last one inserted. Am I wrong ? Is there a
    workaround for this ?

    > If you perform a fetch, then you may get back a different result
    > set (notably if the content of the array controller is filtered)
    > and the ordering may be different (in some situations this might be
    > important to you).  Moreover, the fetch incurs a round trip to the
    > persistent store, whereas the value of arrangedObjects may be cached.
    >
    > mmalc
    >

    I've run a test to check for performances. A fetch is 2-3 times
    slower than arrangedObjects.
  • On Oct 7, 2006, at 12:36 AM, Matteo Rossi wrote:

    >
    >> If you want to perform an operation on the content of a table view
    >> provided by an array controller, then use -arrangedObjects --
    >> that's what it's there for...
    >
    > Well, indeed, I don't want to perform an operation on a tableview, I
    > use arrangedObjects to retrieve all entities of a certain kind and
    > draw them on screen (they are lines); my primary goal is an
    > ***UPDATED*** array of lines; the second one is a fast response. In
    > other words I must be sure that all  entities are correctly
    > synchronized to the ones I creates/removed/modified.  Is it correct
    > that they are ONLY IF the tableview is displayed ? If I hide my
    > tableview (or have no tableview at all) and add an entity
    > programmatically, I think I'll have to run a fetch to retrieve all
    > entities including the last one inserted. Am I wrong ? Is there a
    > workaround for this ?
    >
    It's not clear what you're trying to achieve and why.

    What the array controller contains (and the value of arrangedObjects)
    is determined by the setting of 'automaticallyPreparesContent' and the
    filterPredicate.  It is not determined by the table view.

    Assuming you're only using a single managed object context and only
    one application is updating the store, then setting
    automaticallyPreparesContent to YES means that the array controller
    keeps itself up-to-date with insertions and deletions -- this is
    described in <http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Cla
    sses/NSArrayController_Class/Reference/Reference.html#//apple_ref/occ/instm
    /NSArrayController/setAutomaticallyPreparesContent:
    >.

    mmalc
  • > What the array controller contains (and the value of
    > arrangedObjects) is determined by the setting of
    > 'automaticallyPreparesContent' and the filterPredicate.  It is not
    > determined by the table view.
    >
    > Assuming you're only using a single managed object context and only
    > one application is updating the store, then setting
    > automaticallyPreparesContent to YES means that the array controller
    > keeps itself up-to-date with insertions and deletions -- this is
    > described in <http://developer.apple.com/documentation/Cocoa/
    > Reference/ApplicationKit/Classes/NSArrayController_Class/Reference/
    > Reference.html#//apple_ref/occ/instm/NSArrayController/
    > setAutomaticallyPreparesContent:>.
    Thank you for your help. I think I've found the solution. I manage CD
    lines and use a NSArrayController to modify their properties in an
    information panel. When I draw a new line, I add it programmatically
    by using [initWithEntity:  insertIntoManagedObject] and send a
    notification to update my drawing view. My problem was that if I
    tried to retrieve all lines in drawRect: by usign [myArrayController
    arrangedObjects] I didn't succeed to retrieve the last one I had
    drawn. I think it's due to the fact that the object graph is updated
    once per cycle and NOT NECESSARILY before drawRect was called. My
    first workaround was to execute a fetch. But I've found that the
    correct way is to invoke [moc processPendingChanges]. Thank you
    again, mmalc.
  • On Oct 7, 2006, at 3:37 PM, Matteo Rossi wrote:

    > ank you for your help. I think I've found the solution. I manage CD
    > lines and use a NSArrayController to modify their properties in an
    > information panel. When I draw a new line, I add it programmatically
    > by using [initWithEntity:  insertIntoManagedObject] and send a
    > notification to update my drawing view. My problem was that if I
    > tried to retrieve all lines in drawRect: by usign [myArrayController
    > arrangedObjects] I didn't succeed to retrieve the last one I had
    > drawn. I think it's due to the fact that the object graph is updated
    > once per cycle and NOT NECESSARILY before drawRect was called. My
    > first workaround was to execute a fetch. But I've found that the
    > correct way is to invoke [moc processPendingChanges]. Thank you
    > again, mmalc.

    What I would probably do in your situation is add support to the
    drawing view for bindings, and bind it to the appropriate key in my
    array controller.

    For performance, I would probably cache the information that the view
    receives in its observer notifications, so I don't need to either
    issue fetches or access the bound controller from within my view's -
    drawRect: implementation.

    What all this would get me is the ability to completely decouple my
    view/drawing code from my model and controller code.  This would make
    my view a lot more reusable, or at least able to be enhanced in such a
    way that it could be.

      -- Chris
  • On Oct 7, 2006, at 9:06 PM, Chris Hanson wrote:

    > What I would probably do in your situation is add support to the
    > drawing view for bindings, and bind it to the appropriate key in my
    > array controller.
    >
    Ah, beat me to it  :-)

    For an example, see Graphics Bindings at
    <http://homepage.mac.com/mmalc/CocoaExamples/controllers.html>

    > For performance, I would probably cache the information that the
    > view receives in its observer notifications, so I don't need to
    > either issue fetches or access the bound controller from within my
    > view's -drawRect: implementation.
    > What all this would get me is the ability to completely decouple my
    > view/drawing code from my model and controller code.
    >
    ... and specifically in this case it would mean you don't have to do
    this:

    On Oct 7, 2006, at 3:37 PM, Matteo Rossi wrote:

    > But I've found that the correct way is to invoke [moc
    > processPendingChanges].
    >
    This is in general probably not the correct way to achieve what you
    want.

    mmalc
previous month october 2006 next month
MTWTFSS
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
Go to today