Re: Two simple questions regarding Core-Data
Re: Two simple questions regarding Core-Data
- Subject: Re: Two simple questions regarding Core-Data
- From: "Marcus S. Zarra" <email@hidden>
- Date: Fri, 4 May 2007 15:08:03 -0600
Interesting that your example causes the faults to fire. By removing
the bindings from the equation I was not able to duplicate your
results.
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:[NSEntityDescription entityForName:@"Invoice"
inManagedObjectContext:managedObjectContext]];
[request setPredicate:[NSPredicate predicateWithFormat:@"invoiceNumber == 19"]];
NSError *errord;
NSArray *array = [managedObjectContext executeFetchRequest:request
error:&errord];
if (!array) {
NSLog(@"Error: %@", errord);
return;
}
NSLog(@"Count of invoices: %d\n%@", [array count], array);
id invoice = [array objectAtIndex:0];
id detailSet = [invoice valueForKey:@"invoiceDetails"];
NSLog(@"Count of details: %d\n%@", [detailSet count], detailSet);
--------Output
2007-05-04 14:44:15.634 seSales[25169] Count of invoices: 1
(
<InvoiceEntity: 0x4e82c0> (entity: Invoice; id: 0x5d37860
<x-coredata://799303D2-FFF6-409B-BA4A-396CE56E3864/Invoice/p334> ;
data: <fault>)
)
2007-05-04 14:44:15.650 seSales[25169] Count of details: 5
<_NSFaultingMutableSet: 0x5b33930> (<InvoiceDetailEntity: 0x5d9efb0>
(entity: InvoiceDetail; id: 0x4f1da0
<x-coredata://799303D2-FFF6-409B-BA4A-396CE56E3864/InvoiceDetail/p1230>
; data: <fault>), <InvoiceDetailEntity: 0x4ce240> (entity:
InvoiceDetail; id: 0x4f1dc0
<x-coredata://799303D2-FFF6-409B-BA4A-396CE56E3864/InvoiceDetail/p2140>
; data: <fault>), <InvoiceDetailEntity: 0x5d29320> (entity:
InvoiceDetail; id: 0x4f1d50
<x-coredata://799303D2-FFF6-409B-BA4A-396CE56E3864/InvoiceDetail/p1210>
; data: <fault>), <InvoiceDetailEntity: 0x4cd2b0> (entity:
InvoiceDetail; id: 0x4f1de0
<x-coredata://799303D2-FFF6-409B-BA4A-396CE56E3864/InvoiceDetail/p2217>
; data: <fault>), <InvoiceDetailEntity: 0x4ce200> (entity:
InvoiceDetail; id: 0x5d9e190
<x-coredata://799303D2-FFF6-409B-BA4A-396CE56E3864/InvoiceDetail/p452>
; data: <fault>))
As you can see I am accessing the invoiceDetails through the
relationship and in my output I do not get the items fired. So this
may indicate that the array controller is giving you a proxy object in
your example or some other magic is going on behind the scenes.
NOTE: the OP was looking for a way to perform a "select count(*) from
xxx" which the above code does perform without a performance hit of
firing the faults.
Marcus S. Zarra
Zarra Studios LLC
Simply Elegant Software for OS X
www.zarrastudios.com
On 5/4/07, Robert Walker <email@hidden> wrote:
Marcus,
Ok for my own sanity and full understanding of this, I created a very
simple Core Data application with a button connected to an action
used to count people in a department:
Here's my counting code:
01 (IBAction)countPeople:sender
02 {
03 NSManagedObject *selection = [[arrayController selectedObjects]
objectAtIndex:0];
04 NSLog(@"\n\nDepartment before counting: %@", [selection
description]);
05
06 int count = [[selection valueForKey:@"people"] count];
07
08 NSLog(@"\n\nCount of people: %d", count);
09 NSLog(@"\n\nDepartment after counting: %@", [selection
description]);
10 }
And here are the results:
[Session started at 2007-05-04 15:55:51 -0400.]
2007-05-04 15:55:56.931 FaultTest[3015]
Department before counting: <NSManagedObject: 0x320b00> (entity:
Department; id: 0x320dd0 <x-coredata://9C7E671E-A376-4ED1-AB42-
AC0F88013CE6/Department/p1> ; data: {name = "Department A"; people =
"<relationship fault: 0x320ff0 'people'>"; })
2007-05-04 15:55:56.933 FaultTest[3015]
Count of people: 2
2007-05-04 15:55:56.934 FaultTest[3015]
Department after counting: <NSManagedObject: 0x320b00> (entity:
Department; id: 0x320dd0 <x-coredata://9C7E671E-A376-4ED1-AB42-
AC0F88013CE6/Department/p1> ; data: {
name = "Department A";
people = (
0x31b2f0 <x-coredata://9C7E671E-A376-4ED1-AB42-AC0F88013CE6/
Person/p4>,
0x31c250 <x-coredata://9C7E671E-A376-4ED1-AB42-AC0F88013CE6/
Person/p1>
);
})
Does this not indicate that accessing the count of people, through
the relationship on a department, does indeed fire the fault? Or is
there another way of getting the count without using KVC to access
the "people" relationship on a department (as shown in line 6)?
On May 4, 2007, at 1:03 PM, Marcus S. Zarra wrote:
> Basically, the fetch will return an array of faults if the objects are
> not already in memory. Performing a count on the array will not cause
> the faults to fire since you are not accessing the attributes of the
> objects inside of the array. You are just asking the array how many
> objects it holds.
>
> Personally, I would recommend this method over keeping a count
> attribute in a parent object. It is way too easy for that count to
> get out of sync with the array. Since counting the number objects in
> the relationship will not cause the faults to fire it is safer to get
> this information each time it is requested.
>
> Marcus S. Zarra
> Zarra Studios LLC
> Simply Elegant Software for OS X
> www.zarrastudios.com
>
>
> On 5/4/07, Robert Walker <email@hidden> wrote:
>> Marcus,
>>
>> > Again no. Fortunately when the array is retrieved all of the
>> objects
>> > are "faults" which means they are not loaded into memory yet and
>> your
>> > call to count will not cause them to load. Therefore the memory
>> and
>> > performance hits are negligible.
>>
>> Are you sure that asking for the count would not cause the fault
>> representing a collection to fire? If so that's really impressive.
>> How would Core Data know the number of objects represented by the
>> fault without realizing the fault first?
>>
>> --
>> Robert Walker
>> email@hidden
>>
>>
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden