Editing in a tableview without selecting

2009-11-01 Thread Ben Haller
];

// Add parts
		[tableView addTableColumn:[AKVariableStore  
columnObjectForIdentifier:nameColumnID]];
		[tableView addTableColumn:[AKVariableStore  
columnObjectForIdentifier:equalsColumnID]];
		[tableView addTableColumn:[AKVariableStore  
columnObjectForIdentifier:valueColumnID]];
		[tableView addTableColumn:[AKVariableStore  
columnObjectForIdentifier:swatchColumnID]];
		[tableView addTableColumn:[AKVariableStore  
columnObjectForIdentifier:descriptionColumnID]];


// Set ourselves up to be in charge
[tableView setDelegate:self];
[tableView setDataSource:self];

[tableView setFrame:tableViewFrame];
[tableView sizeLastColumnToFit];
}

return tableView;
}

  My delegate methods (skipping the implementations for the  
unimportant ones):


- (BOOL)tableView:(NSTableView *)aTableView shouldSelectRow: 
(NSInteger)rowIndex

{
return YES;
}

- (BOOL)tableView:(NSTableView *)aTableView shouldEditTableColumn: 
(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex

{
return YES;
}

- (CGFloat)tableView:(NSTableView *)tableView heightOfRow: 
(NSInteger)rowIndex
- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn: 
(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex


  My datasource methods:

- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn: 
(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
- (void)tableView:(NSTableView *)aTableView setObjectValue: 
(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row: 
(NSInteger)rowIndex


  That last datasource method never gets called, if you're wondering.

  The only unusual thing about this tableview is that I set it up in  
code instead of in IB, so I assume the root of the problem is in my  
programmatic setup code.  But where?  I've been hunting for a - 
setEditable:YES method somewhere that I need to call, but I haven't  
found it...


  Any ideas?  Thanks!

Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Editing in a tableview without selecting

2009-11-01 Thread Ben Haller

On 1-Nov-09, at 12:42 PM, Ben Haller wrote:

 Hi all.  I've got an NSTableView that I'd like to be editable.   
Even if I return YES from -tableView:shouldSelectRow: and YES from  
tableView:shouldEditTableColumn:row:, however, editing does not  
actually commence.  The row selects, and I've confirmed with logs  
that both delegate methods are indeed getting called; the tableView  
seems to just decide not to start editing after all.  No other  
console logs appear, so it's not a raise.  Simply not implementing  
the two delegate methods mentioned above does not make any  
difference.  The object value for cell that should enter editing is  
an NSString, and its cell is an NSTextFieldCell.  Is there some  
additional step I have to take to make editing actually commence?


  The title of this thread is a bit wrong, sorry about that.  I was  
originally trying to figure out a way to allow editing without  
selecting, but when I realized I couldn't get editing to happen at  
all, in any case whatsoever, my focus shifted.  :-  I am letting the  
row get selected as normal, and it seems to be selected correctly, as  
my first message says.


Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Editing in a tableview without selecting

2009-11-01 Thread Ben Haller

On 1-Nov-09, at 4:22 PM, Scott Waters wrote:


I'm new to Obj-c / Cocoa but this was helpful in figuring out editable
table views I was trying to create with IB. Maybe it can help you in
your case.

http://www.idevgames.com/forum/showpost.php?p=94784postcount=3

I know I wasn't putting a dictionary object into an array with the
same identifier that I had created in IB. So I could edit my data in
my tableview but as soon as I was done editing it never updated my
array so it my data never changed.


  Thanks for the reference, but the problem I'm seeing is that  
editing doesn't even begin on my tableview.  I double-click on a cell,  
and nothing whatsoever happens.


Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Editing in a tableview without selecting

2009-11-01 Thread Ben Haller

On 1-Nov-09, at 6:01 PM, Graham Cox wrote:


On 02/11/2009, at 4:42 AM, Ben Haller wrote:

But where?  I've been hunting for a -setEditable:YES method  
somewhere that I need to call, but I haven't found it...



Hi Ben,

Have you tried -setEditable:YES on the textfield cell you're using  
for the table column? (Inherited from NSCell). I'm not sure what its  
default state is, documentation doesn't say.


  Just tried it; makes no difference.

  I think I will have to construct a test case to see if I can  
reproduce this in a simple, isolated way.  If that test case  
reproduces the problem, then I will post it somewhere and follow up on  
the list...


Ben Haller
Stick Software


___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: 64 bit cocoa version of HIViewFlashDirtyArea() ?

2009-10-30 Thread Ben Haller

On 30-Oct-09, at 9:17 PM, Sean McBride wrote:


David M. Cotter (m...@davecotter.com) on 2009-10-30 9:04 PM said:


anyone have some sample code for a function that does the equivalent
of HIViewFlashDirtyArea() ?

i'd like to have this i the debug version of my program to help flush
out inefficient invalidating.

or:

how do i fetch the invalid region of an NSWindow* ?


Never tried, but... if I search for flash in this doc:

http://developer.apple.com/mac/library/technotes/tn2004/tn2124.html

I think NSShowAllDrawing might help you.


  I just tried -NSShowAllDrawing YES in arguments to be passed on  
launch and it worked quite nicely.  The only odd thing is that it  
seems to flash each view two times for every one time it gets drawn.   
I verified by other means (let's hear it for NSLog!) that a given view  
was in fact getting called to draw only once, but was flashing twice.   
I don't know if there's a good reason for that behavior or not.  :-   
Apart from that issue, it worked quite nicely.

  Thanks for the tip, Sean.

Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: EXC_BAD_ACCESS when migrating a store, but only sometimes...

2009-10-29 Thread Ben Trumbull
 I've come across a rather perplexing problem which is driving me nuts.  
 I'm attempting to migrate a core data SQLite store to the current  
 model version, and most of the time it works fine. However, sometimes  
 I get an EXC_BAD_ACCESS in the following stack:
 
 objc_assign_strongCast + 19
 -[NSMigrationManager  
 migrateStoreFromURL:type:options:withMappingModel:toDestinationURL:destinationType:destinationOptions:error
  
 :] + 2750
 (My methods...)

If you can reproduce it in a small sample project (with your models, etc, but 
the least amount of custom code), then please file a bug.

One thing you might try is, before creating the NSMigrationManager with 
-[NSMigrationManager  initWithSourceModel:destinationModel:] is creating 2 
empty throw away PSCs, one that uses the source model and one that uses the 
destination model.  Then just release the PSCs and use those models to 
construct the NSMigrationManager.  That should work around the one known GC 
issue here.  

If you're not using GC, than try breaking out Instruments' ObjectAlloc with 
NSZombie detection.

- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Could not merge data-error on save in a single moc app

2009-10-29 Thread Ben Trumbull
 I get a Could not merge changes-error on save in a single moc app 
 (*). The docs state this is a problem of a multi-moc setup:
 
 http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CoreData/Articles/cdTroubleshooting.html
 

Yes, the MOC you are saving refers to data that has changed out from underneath 
it in either the PSC or the database file itself.  This is an optimistic 
concurrency control failure.

 The error does not appear on every system and seems to be related to  
 when save is called. (race condition?) So far I only have users  
 complaining that run Mac OS 10.6. I can rarely reproduce the error  
 myself.
 
 Any pointers where to look?

Well, you can break on -[NSManagedObjectContext init], and -save: to see if you 
really only have 1 MOC.  Other than that, breaking on +[NSError 
errorWithDomain:code:userInfo:] and doing thread apply all bt in gdb is 
usually helpful.

 
 I use garbage collection.
 
 regards
   Ruotger
 
 (*) the context is handed out by a singleton method. I NSAssert() this  
 method is only called by the main thread.  

Well, it's still possible for code to leak it to another thread if, you say, 
pass NSManagedObjects around, and then ask them for their MOC.

- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Help debugging Dangling reference to an invalid object. Core Data error

2009-10-29 Thread Ben Trumbull

On Oct 29, 2009, at 16:55 , Sean McBride wrote:

 On 10/22/09 4:59 PM, Melissa J. Turner said:
 
 I have an entity 'Scene' with a to-many relationship to an entity
 'Target'.  The inverse relationship is also to-many.  Both relationships
 are optional and the delete rule for both sides is nullify.
 
 To repro, I delete all Scenes then try to save.  It gives:
 
 Dangling reference to an invalid object. = null;
 NSAffectedObjectsErrorKey = (
 BSScene: 0x2004ff940 (entity: Scene; id: 0x2004f32a0 x-coredata://
 FCE3E0E3-F187-4C44-BFC3-60D7AF3E579F/Scene/p343 ; ...
 
 This error gives only 4 hits with Google. :(
 
 The problem is that some Targets still have relationships to some
 Scenes!  How can that happen?  It seems like the delete rule is not
 doing its job.
 
 Does the object with the ID x-coredata://FCE3E0E3-F187-4C44-
 BFC3-60D7AF3E579F/Scene/p343 exist in the affected store? What happens
 when you call existingObjectWithID:error:?
 
 Do you know what version of the OS the bad documents were created on? A
 lot changed in the relationship handling area in 10.6 (for the better,
 really and truly ;-), so knowing whether your customers created them on
 10.5.x or 10.6.x would help narrow down the possibilities.
 
 Thanks Melissa and Ben for your replies!
 
 I have been working on this issue for days now and am getting
 increasingly confused. :)
 
 My coworker found a way to create a document (in 10.6.1) with almost the
 same problem as originally described (it complains about the inverse
 relationship instead).
 
 Examination of the XML document (as text) suggests that the object graph
 is ok.
 
 To repro: 1) open said document 2) delete a particular managed object 3)
 attempt to save - receive dangling reference error.  Repros 100%.
 
 I've also found that changing a particular line of my code prevents
 (100%) the error from occurring.  Said line only runs when the document
 is opened (as a result of a controller getting a KVO notification).
 
 The entities in question are Scene and Target.  Scene has a to-many
 'targetsWeak' relationship.  Target has a to-many 'scenesWeak'
 relationship.  They are inverses.  They are optional and nullify.
 
 The code snippet in question:
 
 NSSet* currentTargets = [scene targetsWeak];
 NSSet* additionallyDesiredTargets = some fetch result;
 BOOL isEqual = [currentTargets isEqualToSet:
additionallyDesiredTargets];
 assert (isEqual);
 //if (!equal)
 {
   [scene addTargetsWeak:additionallyDesiredTargets];
 }
 
 It turns out that isEqual is always YES in this limited repro case.
 Therefore, I don't really need to change 'targetsWeak' (the 'if' body).
 But if I do anyway (the commented 'if'), I get the 'dangling reference'
 error.  If I don't, I don't.
 
 Even if I do [scene addTargetsWeak:[scene targetsWeak]] I get the error.
 
 Does this make any sense to anyone?


The only caveat is you cannot change relationships from within -awakeFromFetch. 
 This is documented:
http://developer.apple.com/mac/library/documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObject_Class/Reference/NSManagedObject.html#//apple_ref/occ/instm/NSManagedObject/awakeFromFetch

Otherwise, if this repros 100% of the time, file a bug and we'll take a look at 
it.

- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Core Data: Undoing Cut-Paste, Drag-Drop between documents

2009-10-27 Thread Ben Trumbull
 Although some users might expect that the employee moves from Document  
 2 back to Document 1, that does not happen.  Because each document has  
 its own managed object context and own undo manager, because Document  
 2 is active, the employee disappears from there.  But order to make it  
 reappear in Document 1, user also needs to activate Document 1 and  
 click Edit  Undo *again*.
 
 One could argue that there is no problem.  Mac Users understand that  
 Undo is per-document.  They will instantly realize that they did two  
 *do* operations in two different documents (Cut in Document 1, Paste  
 in Document 2) to get where they are at, so they expect that two  
 *undo* operations, one in each document, will be required to get  
 back.  A highly-skilled Core Data developer might even be able to set  
 the correct undo actions, Undo Paste Employee and Undo Cut  
 Employee, which will help cue in those users with unrealistic  
 expectations.
 
 But this answer is not as plausible if the user makes the move using  
 drag-drop instead of cut-paste.  (Drag-drop is not implemented in  
 DepartmentAndEmployees, but it is common in real apps.)  Clearly, the  
 user has now performed only one operation, and might rightfully expect  
 it to be undoable with a single Undo.
 
 I suppose that the developer of such an app could replace the undo  
 manager in each document, upon creation or loading, with a single,  
 common undo manager.  But I fear that this would cause hundreds of  
 unintended under-the-hood consequences in Core Data, and am loathe to  
 think about it.  Has anyone ever done this?
 
 Another alternative:  In the drag-drop implementation, before doing  
 the *delete* operation, temporarily disable undo registration in the  
 source document.  Then, explicitly register with the undo manager of  
 the destination document an action which would insert an object with  
 the old object's attributes into the source document's moc.  An  
 equivalent trick would probably work in a non-Core-Data document, but  
 I suspect that Core Data's under-hood magic wouldn't be too pleased  
 with this.
 
 In either case, there's the little issue of what if the source  
 document is closed, then later this Undo action gets invoked.  Setting  
 a flag to say that you've got Document 1's stuff on your undo stack,  
 and removing all undo actions when Document 1 is closed would probably  
 be a good idea, but this is starting to get messy.

You can queue up and control the undo actions in each document's undo manager.  
But you're still left with the problem that undo will be wired to the front 
most document, and there's no meta-undo manager for cross-document undo 
operations.

I don't see how this is a Core Data issue.  Either you can coordinator undos 
across multiple different undo managers, or you can't.  Well, I suppose unless 
you want to have all your documents share an undo manager, which Core Data 
won't like.  But that's crazy talk :-)

As a user, I would never expect undo to go modifying the contents of other 
windows in a document based app.  Take TextEdit for example.  The behavior you 
suggest is completely inappropriate for TextEdit.  I have separate documents 
because I'm working on separate things.  I'd be pretty frustrated if I couldn't 
move things between documents without borking undo.

The behavior you describe is more commonly associated with non-document apps 
like iCal or Address Book.  They use a single undo manager for the user edits.

- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: How to run a panel that customizes a new NSDocument

2009-10-22 Thread Ben Haller
 hope I've caused no lasting offense.



Read this:

	http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/CreateCustomizeNSError/CreateCustomizeNSError.html#/ 
/apple_ref/doc/uid/TP40001806-CH204-BAJIIGCC


and note particularly:

Note: Cocoa methods that indirectly return error objects in the  
Cocoa error domain are guaranteed to return such objects if the  
method indicates failure by directly returning nil or NO. With such  
methods, you should always check if the return value is nil or NO  
before attempting to do anything with the NSError object.


NSDocumentController methods play by these specific rules, so your  
overrides must do so too. Returning the user cancelled error is a  
special-case refinement of the technique that permits the (ultimate)  
suppression of the error alert. (The same technique is useful in  
cases where there really is an error but you want to display the  
alert yourself, but you want to prevent the NSDocumentController  
from complaining a second time.) It's not really well documented,  
but -- I hope you noticed -- you got the answer for free just by  
asking the question.


  OK, very good to know.  As I noted in an earlier post, I was misled  
by the NSError documentation that says:


In general, a method should signal an error condition by—for example— 
returning NO or nil rather than by the simple presence of an error  
object. The method can then optionally return an NSError object by  
reference, in order to further describe the error.


  Thanks for the ref to the better doc; I will read that, and if it  
seems appropriate, will file a doc bug on the item that misled me.


  As for I hope you noticed -- you got the answer for free just by  
asking the question, yes, of course I appreciate the list's  
helpfulness, and your helpfulness specifically, and I think I'm  
careful to thank people. There's no need to be snippy.  I've posted  
hundreds of replies to this list and other cocoa-related lists helping  
people out myself, although that was many years ago now, since I took  
a multi-year break from coding recently.  I'm sure there are old- 
timers around who remember me.


  So, thank you for your help.  Let's move on.

Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Search on Core data Table issue?

2009-10-22 Thread Ben Trumbull

Not sure if this is the right place (I am sure someone will let me
know if it is not)  I have a iPhone application that has a UITable
view that is backed by core data.  I want to perform a reducing search
so that only the items starting with the characters entered into the
search bar are shown.  This is normally done with delegate - (void)
searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)
searchText no problem.  I am a little confused as I am new to Core
Data how to do this.  One of the big problems as I see it is going to
be updating the interface to let it know what to present.  I assume an
alternative NSFetchedResultsController needs to be sent to the
UITableView.


You're basically on the right track.


So here are my issues:
1) I assume I need to create a  NSFetchedResultsController with only
the correct items in it then tell the UITableView to use this as the
dataSource and reload the table?


Yes.  Most of the Apple apps use an overlay, so it's also a different  
UITableView entirely.  See search in the Contacts app, for example.



2) is there a better way than executing a full sorted fetch and
removing those objects that do not conform.  ie is there a way of
doing a select where type fetch?


I'm not sure exactly what you mean by select where type fetch.  What  
type ?


The typical pattern is if the user typing has gone from a 0 length  
string to a 1 character string, you'll need to do a fetch.  (that  
includes the user deleting a character and starting over).  If the  
string already has 1 or more characters, you can choose between a new  
fetch, or simply an in memory filter of the previous results.  The  
results should always be sorted, so you can binary search the range to  
filter, instead of filtering all the strings.


The balance of when to fetch and when to filter is complicated, and  
depends on your data set, as well as your UI.  If you have an  
extremely large data set, you should use a fetch limit, so that the  
user cannot get back all the results until they've entered a  
sufficiently discriminating search string.  If the number of results  
you get back is equal to the fetch limit, you can consider executing a  
count request or just saying and more


If the number of results is small, then it's much faster to filter the  
old results in memory.  Fetching will save you a lot of memory, but it  
is I/O so it has a high fixed cost (like ~2ms on a desktop).  You'll  
want to balance the two.  You might start out with a threshold of 100  
and tune from there.



Thanks in advance and sorry if this is a dumb question.


It's not.

- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Help debugging Dangling reference to an invalid object. Core Data error

2009-10-22 Thread Ben Trumbull
 Core Data is giving me a validation error when I try to save a document
 after making a simple change.
 
 I have an entity 'Scene' with a to-many relationship to an entity
 'Target'.  The inverse relationship is also to-many.  Both relationships
 are optional and the delete rule for both sides is nullify.
 
 To repro, I delete all Scenes then try to save.  It gives:
 
 Dangling reference to an invalid object. = null;
 NSAffectedObjectsErrorKey = (
  BSScene: 0x2004ff940 (entity: Scene; id: 0x2004f32a0 x-coredata://
 FCE3E0E3-F187-4C44-BFC3-60D7AF3E579F/Scene/p343 ; ...
 
 This error gives only 4 hits with Google. :(
 
 The problem is that some Targets still have relationships to some
 Scenes!  How can that happen?  It seems like the delete rule is not
 doing its job.

This error happens when the MOC for a destination object is nil, the object is 
in a relationship but marked deleted, or the object in a relationship has a 
temporary objectID but is not marked inserted.  Using 
refreshObject:mergeChanges:NO on an object with pending changes can do some of 
that, as can assigning a deleted object to new relationships after delete 
propagation has run.

- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: How to run a panel that customizes a new NSDocument

2009-10-21 Thread Ben Haller

On 21-Oct-09, at 12:57 AM, Graham Cox wrote:


On 21/10/2009, at 3:43 PM, Ben Haller wrote:


There must be a good, clean way to do this.  Anyone?


Well, the expected way is to have different types for your  
documents. You can still map them all to the same class, and  
discriminate in the -initWithType:error: method to set up the  
appropriate model.


However, if you really can't or don't want to do that, I think what  
you've done is right. Because you have a special designated  
initializer, you have no option but to manually make the controllers  
and add the document to the controller.


  OK, I've switched over to an NSDocumentController and using  
different types for my different models.  That turned out to be a  
forced move, because NSApplication's delegate method - 
applicationOpenUntitledFile: does not get called when the user chooses  
New from the File menu; that seems to go right to  
NSDocumentController.  -applicationOpenUntitledFile: only seems to get  
called for the new document created when an app is launched or brought  
front without an open document.  I could have started changing the  
actions for menu items and so forth, but I decided that since my app  
is document-based, I ought to go with the document architecture.  So I  
now have an NSDocumentController subclass, and I override  
openUntitledDocumentAndDisplay:error:.  That seems to be in the code  
path for all kinds of new documents.
  However, I still find this architecture quite unsatisfying.  My - 
openUntitledDocumentAndDisplay:error: subclass still needs to do way  
too much work:


- (id)openUntitledDocumentAndDisplay:(BOOL)displayDocument error: 
(NSError **)outError

{
NSString *chosenModelName = [AKNewModelController runNewModelPanel];

if (chosenModelName)
{
NSError *error = nil;
		AKDocument *document = [self  
makeUntitledDocumentOfType:chosenModelName error:error];


if (error)
{
if (outError)
*outError = error;
return nil;
}

[self addDocument:document];

if (displayDocument)
{
[document makeWindowControllers];
[document showWindows];
}

return document;
}

return nil;
}

  The sequence of -makeUntitledDocumentOfType:error:, then  
makeWindowControllers, then showWindows, is already in super, but I  
don't have any way to make super do it.  So I have to duplicate that  
sequence in my own code, which makes my code vulnerable to  
architectural changes in NSDocument.  I gather this sequence has  
already changed at least once in the past, so it is clearly fragile.
  There really must be a better way to do this; I feel like I'm  
running at counter purposes to the design of the framework.  Anyone  
have any better suggestions?
  I'm curious as to why -makeUntitledDocumentOfType:error: doesn't do  
the work of adding the document, setting up its windowController,s and  
showing the windows.  That would seem like the natural design to me,  
rather than making everyone that calls that method do that work  
themselves.  Is there a reason for this design?


Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: How to run a panel that customizes a new NSDocument

2009-10-21 Thread Ben Haller

On 21-Oct-09, at 6:55 PM, Ben Haller wrote:

 OK, I've switched over to an NSDocumentController and using  
different types for my different models.  That turned out to be a  
forced move, because NSApplication's delegate method - 
applicationOpenUntitledFile: does not get called when the user  
chooses New from the File menu; that seems to go right to  
NSDocumentController.  -applicationOpenUntitledFile: only seems to  
get called for the new document created when an app is launched or  
brought front without an open document.  I could have started  
changing the actions for menu items and so forth, but I decided that  
since my app is document-based, I ought to go with the document  
architecture.  So I now have an NSDocumentController subclass, and I  
override openUntitledDocumentAndDisplay:error:.  That seems to be in  
the code path for all kinds of new documents.
 However, I still find this architecture quite unsatisfying.  My - 
openUntitledDocumentAndDisplay:error: subclass still needs to do way  
too much work:


  Furthermore, the way I have it coded now does not even work.   
Clicking cancel in my choose a model window returns a nil string to  
my NSDocumentController subclass - 
openUntitledDocumentAndDisplay:error:, and I see that nil and  
immediately return nil myself, since the user has cancelled.  That  
results in a raise from the Kit:


#0  0x964ef688 in objc_msgSend ()
#1  0x93d7e9e6 in -[NSDocumentController(NSInternal)  
_fixedFailureReasonFromError:] ()

#2  0x93d7c2fd in -[NSDocumentController _willPresentCreationError:] ()
#3  0x9393d2d4 in -[NSDocumentController(NSInternal) _openUntitled] ()
#4  0x9393d109 in -[NSApplication _doOpenUntitled] ()
#5  0x9393c7ed in -[NSApplication(NSAppleEventHandling)  
_handleAEOpen:] ()


  Apparently if -openUntitledDocumentAndDisplay:error: is called, it  
*must* create a new document, otherwise it is a raise-worthy error.   
So my whole design is once again invalid.  I'm not even sure how I  
might fix it.  Overriding -newDocument instead doesn't seem to be an  
option, because it doesn't have any way to pass on the type chosen to  
the rest of the call chain.  The docs for -newDocument say this:


It invokes openUntitledDocumentAndDisplay:error: with the document  
type (first argument) being the first one specified in the  
CFBundleDocumentTypes property (defined in Info.plist); the document  
type determines the NSDocument subclass used to instantiate the  
document object.


  But that seems to be obsolete; the document type is not passed to - 
openUntitledDocumentAndDisplay:error: at all.  I wish it were; then  
overriding -newDocument would clearly be the right architecture.


  This is driving me crazy.  Tons of apps want to do this (run a  
panel on a new document request, and make a new document configured  
based on the results of that panel).  There must be an easy way to do  
it in the NSDocument architecture; I'm just trying to tap in at the  
wrong point, somehow.  Help!


Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-20 Thread Ben Haller

On 20-Oct-09, at 6:54 AM, Uli Kusterer wrote:


On 19.10.2009, at 23:58, Ben Haller wrote:


On 19-Oct-09, at 5:27 PM, Dave Keck wrote:


Would NSView's -getRectsBeingDrawn:count: help?


Well, I'm already using it in my own code where appropriate.  (Or  
actually I'm using -needsToDrawRect:).  But the problem is that a  
whole bunch of NSTableView cells are getting drawn that never got  
invalidated.


That's like saying: I'm using the setter, why would I need to use  
the getter?


The dirtyRect parameter passed to drawRect: is the union of all  
redraw rectangles. So, it's the smallest rect that encloses all the  
dirty rects. drawRect: does not get called for each redraw rect. If  
you want the individual sub-rects, use getRectsBeingDrawn:count: and  
loop over all those rects and draw the individual parts.


  Uh, Uli, reread what I typed.  I did not say or actually I'm using  
setNeedsDisplayInRect:.  -needsToDrawRect is a shorthand for exactly  
what you propose: calling -getRectsBeingDrawn:count: and looping over  
those rects.  From the docs for -needsToDrawRect:


It gives you a convenient way to determine whether any part of a given  
graphical entity might need to be drawn. It is optimized to  
efficiently reject any rectangle that lies outside the bounding box of  
the area the receiver is being asked to draw in drawRect:.


  So whether -needsToDrawRect or -getRectsBeingDrawn:count: is a  
better solution depends mostly upon taste, and a little bit on how  
many tests you intend to do in your draw method (i.e. efficiency to  
testing).  For my purposes, doing a total of two tests, - 
needsToDrawRect is fine.


Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-20 Thread Ben Haller

On 20-Oct-09, at 6:59 AM, Uli Kusterer wrote:


On 20.10.2009, at 03:02, Ben Haller wrote:
As for NSTableView, it does appear to be doing minimal drawing.  So  
I guess all the string-drawing overhead I see in Sampler is just  
from the single column that is updating, which is unfortunate since  
it means I have no room for optimization.  I never imagined it  
would take so much time just to draw the one column I dirtied.


This may help to optimize after all:

http://zathras.de/blog-cocoa-text-system-everywhere.htm


  This is interesting, and I've done this sort of thing in the past  
quite a bit actually.  I'm surprised by one bit of it, though, where  
it says:


...sometimes you need better performance than the NSStringDrawing  
category will provide...


implying that doing things this way is faster than NSStringDrawing.   
Is that actually true?  Why would that be?  NSStringDrawing does more  
or less exactly this, doesn't it, using cached a cached textstorage/ 
layout/container set?  If NSStringDrawing is less efficient than doing  
it yourself, where does that inefficiency lie, and why doesn't Apple  
fix that inefficiency?  Presumably because Apple's way has some other  
benefit?  So what is that benefit?  I.e. I'm trying to understand what  
the tradeoffs are here.


  In the past, playing around with such things, the big win I've  
noticed over NSStringDrawing comes up only if you need to both measure  
and draw the same string.  Then you set everything up with your string  
once, measure and draw, and layout needs to happen only once.  So  
drawing centered or right-aligned text is faster -- almost twice as  
fast -- doing it yourself.  If there's a way to get the same speedup  
from Apple's API's I'm not aware of it; AFAIK even - 
[NSAttributedString drawWithRect:options:] doesn't let you draw a  
string centered or right-aligned in the rect, which seems like a big  
oversight.  I've just logged 7318495 on that.


  But if you're drawing text left-aligned, and thus don't need to  
measure it, is there any speedup doing things yourself?


Cheers,

Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-20 Thread Ben Haller

On 20-Oct-09, at 8:15 AM, Graham Cox wrote:


On 20/10/2009, at 11:03 PM, Ben Haller wrote:

AFAIK even -[NSAttributedString drawWithRect:options:] doesn't let  
you draw a string centered or right-aligned in the rect, which  
seems like a big oversight.  I've just logged 7318495 on that.


That's not the case - NSAttributedString takes its left/right/center/ 
justified setting from the NSParagraphStyle attribute attached to  
the string. If it's not there, it defaults to natural alignment for  
the font (left for English).


  Oh!  Good to know.  Didn't occur to me somehow!


I.e. I'm trying to understand what the tradeoffs are here.


Convenience versus speed. Setting up a text layout system  
programatically is quite involved, and for a high-level solution  
that is equivalent to olde-worlde DrawThemeTextBox the string  
drawing methods do that for you. But they have to build up and tear  
down a text system for every call, so incur this overhead and can't  
cache any layout information. I still think it's the case (borne out  
by profiling here) that glyph rendering still dominates the process  
however.


But if you're drawing text left-aligned, and thus don't need to  
measure it, is there any speedup doing things yourself?


Yes, if you are drawing the same string over and over again (as in  
repeated refreshes of the same string in a view). The question is  
whether the speed-up matters. If you have thousands of text objects  
in your view, probably yes. If just one or two, probably not.  
There's no need to (and you can't) draw faster than 60 fps so you  
have ~16mS to draw everything. If it takes longer, text caching etc  
may help.


  Ah, yes, that is true, repeated drawing of the same string would be  
a big win for this.


  Uli had much the same to say.  Good points.  Thanks guys.

Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


How to run a panel that customizes a new NSDocument

2009-10-20 Thread Ben Haller
  Hi all.  I've got an NSDocument-based class that can be based upon  
a variety of models.  The documents are the same type in any case,  
but they are configured differently based upon their model.  When the  
user chooses New, or when the app is launched, I want to run a panel  
for the user to choose their desired model.  Once they dismiss the  
panel, a document using that model will be created.  I.e. very much  
like how Interface Builder runs a panel where you choose the sort of  
nib you want to make, and then it makes you a new nib of that sort.
  The question is how to do this.  I see the stuff in NSDocument/ 
NSDocumentController having to do with types but that does not seem  
relevant; that would be for an app that could open and save both .txt  
and .rtf files, for example.  All of my documents are of the same  
type, they just have different initial state.
  What I have ended up with, after a fair amount of fruitless  
searching in the NSDocument docs, is this method in my application  
delegate:


- (BOOL)applicationOpenUntitledFile:(NSApplication *)theApplication
{
AKModel *chosenModel = [AKNewModelController runNewModelPanel];

if (chosenModel)
{
		AKDocument *newDocument = [[AKDocument alloc]  
initWithModel:chosenModel];


[newDocument makeWindowControllers];
[newDocument showWindows];

		[[NSDocumentController sharedDocumentController]  
addDocument:newDocument];


return YES;
}

return NO;
}

  I don't like it very much though.  It works, but it hard-codes the  
sequence of -makeWindowControllers, then -showWindows, then - 
addDocument:, all of which NSDocumentController ought to be doing for  
me.  I wonder if I need to subclass NSDocumentController instead, but  
it isn't really clear to me how to do that to achieve this. I could  
override -openUntitledDocumentAndDisplay:error:, and run my model  
chooser panel inside my override, but how do I get the model the user  
chose into the new document if the NSDocumentController creates it for  
me?  Right now I pass the model in to the document's -initWithModel:  
method.  I could refactor things so that the document created is  
generic and model-less, and then set a model on it after it has  
constructed; but that would be highly inconvenient, as it happens,  
because the windows the document makes depend upon its model, and the  
document's windows get shown by NSDocumentController before it would  
return control to me (i.e. inside [super  
openUntitledDocumentAndDisplay:error:] returns).

  There must be a good, clean way to do this.  Anyone?

Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Dirty rects getting merged together makes for inefficient drawing

2009-10-19 Thread Ben Haller
  Hi all.  I expected this to be an FAQ, but my searches have turned  
up nothing relevant, so here goes.


  I've got a window with a view hierarchy like this:

1. Superview that does no drawing and is not opaque

A. Subview #1: a tableview that is opaque
B. Subview #2: a graph view that is opaque
C. Subview #3: another graph view that is opaque

  The tableview is on top, the two graph are on the bottom, on the  
left and on the right respectively.  My app alternates calculating and  
drawing the results.  Typically, what needs to get drawn is *one*  
column of the tableview, plus both graphs.  I'm carefully calling  
setNeedsDisplayInRect: for only the bits that need to be drawn; I'm  
using [frameOfCellAtColumn:row:] to get the frame of the cells that  
need to be redrawn, and invalidating only them, for example.


  If I turn off all redrawing of the graphs, then Quartz Debug shows  
me that my invalidating in the tableview is minimal; only the column  
that needs to be drawn flashes.  If I turn off all redrawing of the  
tableview, QuartzDebug similarly shows that my invalidating in the  
graphs is minimal.  So taken separately, it's all good.  But when  
drawing of all the views is turned on, somebody is merging together  
the dirty rects and causing pretty much the entire content of the  
window to redraw.  This means that a ton of extra table cells are  
redrawing unnecessarily, and I see the overhead from this very clearly  
in Instruments/Sampler (text drawing is not fast!).


  So my question is: is there any way I can exert any control over  
the merging of dirty rects?  I thought maybe adding some vertical  
space between the tableview and the graph views would disconnect  
them and make the dirty rects get handled separately; but no dice;  
even adding 100 pixels of vertical space doesn't prevent the merge.   
Is the merging dependent upon the view hierarchy or opacity in some  
way?  Or are there CG calls somewhere in the bowels that I could use  
to change a merge threshold or something?


  I'm not sure whether this is a Cocoa or a CG question really, but  
since I'm using nothing but Cocoa calls at present, I figured I'd try  
this list first...


  Thanks!

Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-19 Thread Ben Haller

On 19-Oct-09, at 5:27 PM, Dave Keck wrote:


Would NSView's -getRectsBeingDrawn:count: help?


  Well, I'm already using it in my own code where appropriate.  (Or  
actually I'm using -needsToDrawRect:).  But the problem is that a  
whole bunch of NSTableView cells are getting drawn that never got  
invalidated.  I would certainly hope that NSTableView is using one of  
these minimal-drawing mechanisms, and I assume that it is.


  I think the problem is deeper (based upon what flashes under Quartz  
Debug): I think the dirty rects are actually getting consolidated such  
that NSTableView no longer has the information it needs to do minimal  
drawing.  I could be mistaken about that, though, if the flashes in  
Quartz Debug show only the area that Quartz is choosing to blit over,  
and not necessarily the area that was considered dirty and redrawn.   
(i.e. if it brings over merged areas for efficiency, for some reason;  
but that seems unlikely...)


Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Why does my font come out looking fuzzy?

2009-10-19 Thread Ben Haller
 Yes, it sounds like the suggestions I've gotten for modifying the  
antialiasing behavior would probably be helpful.  I have solved the  
problem by simply snapshotting the LCD digit images and writing a  
little control that displays a number using those snap images.  Seemed  
simpler, sadly.  Works great.  Thanks to the posters, though; CALayer  
and related concepts are quite new to me, so it is good to develop  
some mental context surrounding them!


Ben Haller
Stick Software


On 19-Oct-09, at 6:24 PM, Dalmazio Brisinda wrote:

Kyle's explanation #1 was spot on for my application. I had an  
NSSearchField in a custom window and view which was not displaying  
quite correctly. It looked as if it was not being anti-aliased.  
Going into Interface Builder, I noticed I had selected the Wants  
core animation layer switch for the control. Turning this off  
corrected the problem.


Best,
Dalmazio



On 2009-10-17, at 9:27 PM, cocoa-dev-requ...@lists.apple.com wrote:


You need to post a screenshot of what you're seeing.

I can think of two possibilities off the top of my head:
1) You're rendering text into a CALayer (especially a CATextLayer).
Without some tweaking, CALayer can't do subpixel antialiasing (aka  
LCD

antialiasing), because it doesn't have the existing backing store to
composite against.
2) You're overdrawing the text and are therefore ruining the
antialiasing, producing a distorted image.

Again, screenshot is pretty much mandatory here.

--Kyle Sluder


___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/bhcocoadev%40sticksoftware.com

This email sent to bhcocoa...@sticksoftware.com


___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-19 Thread Ben Haller

On 19-Oct-09, at 5:58 PM, Greg Guerin wrote:


Ben Haller wrote:


1. Superview that does no drawing and is not opaque

A. Subview #1: a tableview that is opaque
B. Subview #2: a graph view that is opaque
C. Subview #3: another graph view that is opaque



Obvious experiment: set the superview to be opaque.


 Indeed.  Already tried it (right after posting), and it makes no  
difference.  I'd try rearranging the view hierarchy to test the  
effects of that, but that isn't trivial, because it is arranged  
programmatically, so I'm hoping someone has already explored this...
 More generally, I am interested in knowing how this mechanism works,  
beyond just fixing my immediate problem, so I hope somebody can  
comment on that more generally.  And whether there is any way to  
affect it, beyond my immediate case.  I find nothing in the docs about  
it.


Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-19 Thread Ben Haller

On 19-Oct-09, at 6:53 PM, Andy Lee wrote:

On Monday, October 19, 2009, at 05:58PM, Ben Haller bhcocoa...@sticksoftware.com 
 wrote:

 I think the problem is deeper (based upon what flashes under Quartz
Debug): I think the dirty rects are actually getting consolidated  
such

that NSTableView no longer has the information it needs to do minimal
drawing.


To test this theory, might it help to use a subclass of NSTableView  
whose drawRect: method prints the rectangle passed to it, and see  
what happens when your graph views do and do not do any drawing?   
And maybe the result of getRectsBeingDrawn:count: as well?


  Just did this.  The results are interesting.  Two points of note:

- my tableview does seem to be getting passed a nicely limited dirty  
rect, even though Quartz Debug flashes a much larger area.  So  
apparently flashes in Quartz Debug are only indicative of what Quartz  
is choosing to blit over to the screen, not what is actually getting  
updated.  If so, it would be useful to have a new checkbox in Quartz  
Debug that flashed only the areas actually getting marked as dirty, I  
think, so that one could check one's minimal-redraw correctness.  I  
logged 7317630 on this.


- there do seem to be some weirdnesses in the dirty rect accumulation  
code.  For example, when I call -getRectsBeingDrawn:count: and log the  
results, I typically see something like this:


count == 2
rects[0] == {{47, 12}, {45, 215}}
rects[1] == {{47, 0}, {45, 12}}

  So abutting rects of the same width are not getting merged  
together.  Oddly, the dividing line between these rects is not at a  
line boundary in my tableView; a bunch of lines get accumulated  
together into the tall rect, and then the topmost line gets split  
between the tall rect and the little rect.  I have no theory as to why  
this would be.


  As for NSTableView, it does appear to be doing minimal drawing.  So  
I guess all the string-drawing overhead I see in Sampler is just from  
the single column that is updating, which is unfortunate since it  
means I have no room for optimization.  I never imagined it would take  
so much time just to draw the one column I dirtied.


  So, sorry for the false alarm.  The main take-home point I get out  
of all this is that Quartz Debug flashes the areas being blitted over,  
which are not the same as the areas marked dirty or the areas  
requested to be redrawn!


Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-19 Thread Ben Haller

On 19-Oct-09, at 10:40 PM, Andy Lee wrote:

Come to think of it, another experiment would have been to add  
logging to the cells used for the other table columns, to see if  
their drawing code was actually being called.


  Yeah, I did that.  See my previous post.  The upshot is that the  
table is correctly doing minimal redraws.


Sorry if I missed this, but is the string-drawing overhead  
noticeable to the user?  If so, and it's because you're redrawing  
very frequently, maybe you could throttle redrawing to, say, 2-4  
times per second.  There's something called coalesced updates that  
might help.


  I'll check it out.  I kinda want it to redraw a lot really really  
fast, though, because it looks cool.  ;-  I'm throttling my drawing  
to 60 frames per second at present, and then I'm trying to optimize  
the drawing code so that it takes as little time as possible, so that  
as much of each 1/60th second is left to calculate in as possible.   
Maybe I will make the tableView update every 1/30th of a second, and  
update everything else every 60th since it all draws faster.  :-


Does the table column's cell have to do much work to get the string  
it needs to draw (a gross example would be querying a database)?   
Maybe caching would help.


  Nope, all the time is in the string-drawing stuff inside AppKit.

I don't know how much overhead is in cell drawing, but maybe you  
could write your own cell class that doesn't, for example, check  
whether the string needs to be truncated.


  IIRC it wasn't stuff like that.  It was setting up the text storage  
and the typesetter, and then doing the actual drawing, I think.   
Nothing I could reasonably optimize, I think, without getting  
extremely dirty.


There's a section in the docs on optimizing drawing.  I must admit I  
haven't read it, but maybe it contains something that would help in  
your case?


  Read that.  Useful tips, and it did prompt me to put in checks for  
whether parts of my views are inside the dirty rects or not, and to  
make more of my views opaque.


Sorry for all the might's and maybe's --I'm hoping one of my stabs  
in the dark will help.


  Well, I'm curious about the coalesced update thing.  The only ref I  
find through Google is here:


http://developer.apple.com/mac/library/documentation/Performance/Conceptual/Drawing/Articles/CocoaDrawingTips.html

and I don't think that's what you're referring to.  AppKiDo (which I  
still love :-) doesn't find any APIs with coalesce in their name  
that are drawing-related.  Can you give me a pointer?


  Thanks!

Ben Haller
Stick Software


___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Why does my font come out looking fuzzy?

2009-10-18 Thread Ben Haller

On Oct 17, 2009, at 7:46 PM, Ben Haller wrote:





Copied the TrueType font from Instruments into my project, added  
the necessary key to my Info.plist, set the font using [NSFont  
fontWithName:...], and hey presto, there the font is in my app.  
Only... it doesn't look as nice.  It's less crisp.  Kind of fuzzy.   
The corners don't look sharp.


  OK, this is all replying to various helpful folks who replied to  
that:


On 17-Oct-09, at 10:52 PM, Kyle Sluder wrote:


You need to post a screenshot of what you're seeing.


  OK:

http://www.sticksoftware.com/textrendering/

  The point size in Instruments is probably 18, but I tried 19 just  
in case and it doesn't look right either.



I can think of two possibilities off the top of my head:
1) You're rendering text into a CALayer (especially a CATextLayer).
Without some tweaking, CALayer can't do subpixel antialiasing (aka LCD
antialiasing), because it doesn't have the existing backing store to
composite against.
2) You're overdrawing the text and are therefore ruining the
antialiasing, producing a distorted image.


  I'm using an NSTextField to do the text drawing.  It certainly  
renders text antialiased.  In any case, the renderings do look  
antialiased; the edges are not sharply on pixel boundaries (see the  
top of the 5, for example).  It just isn't the same appearance as in  
Instruments.


On 17-Oct-09, at 11:43 PM, Clark S. Cox III wrote:

There's also the possibility that the text isn't being drawn  
properly aligned to the pixel grid.


  I tried making the NSTextField have a frame offset by 0.5 pixels,  
just in case, but that made no visible difference to the rendering.  I  
suspect NSTextField corrects for such misalignment.  So unless the  
font is actually *designed* to be drawn misaligned to the grid, I  
think I'm OK in this department.


On 18-Oct-09, at 1:32 AM, Jens Alfke wrote:

Is the point size the same? If this is a special-purpose font, it  
might have some hinting for the specific point size used in  
Instruments. You might need to compare the character heights up- 
close with Pixie or something.


  I counted pixels in Pixie, and it looks to me like Instruments is  
18-point.  It's a bit hard to tell with the antialiasing going on, but  
they are somewhere from the 18-point rendering to the 19-point  
rendering I posted (see link above).


  Now I'm wondering whether Instruments is actually even using this  
font.  I think it might be a red herring.  Note that the time view in  
instruments appears to be monospaced, whereas the snapshots of my  
rendering using the font show that it is not a monospaced font.  And  
note that their colons are centered vertically, while mine using the  
font are oddly low in their position.  The font may be a leftover from  
a previous implementation, perhaps.
  However, a troll through the images in Instruments does not reveal  
any digit images.  Although it is an interesting exercise anyway; many  
of their button images and such are PDFs, which is intriguing.
  Anyhow, I think it's probably time to abandon this quest, unless  
someone has a good idea of how to proceed.  Spiffy LCD-style display  
on my generation counter will just have to wait.


Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Why does my font come out looking fuzzy?

2009-10-17 Thread Ben Haller
 So, I like the LCD-style font that Instruments uses to show the time  
counter at the top center of the window.  Thought I might use it  
myself for an in-house project (not for release).  Copied the TrueType  
font from Instruments into my project, added the necessary key to my  
Info.plist, set the font using [NSFont fontWithName:...], and hey  
presto, there the font is in my app.  Only... it doesn't look as  
nice.  It's less crisp.  Kind of fuzzy.  The corners don't look  
sharp.  It no longer looks LCD.  What's going on here?  I assume it  
has to do with rendering differences between different typography  
engines, and hinting, and TrueType (or in this case FalseType,  
perhaps), and so forth.  My basic question: is there a way I can get  
my Cocoa app to show this font as nicely as it appears in  
Instruments?  I would have guessed that Instruments was itself a Cocoa  
app, so I'm surprised there's a difference.  Anybody know what's going  
on?  I am now considering taking little screenshots of each digit and  
rolling my own pseudo-font using image blits.  Please save me from  
that fate.


Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: odd behavior with NSError?

2009-10-16 Thread Ben Trumbull

(response is pedantic for the purposes of the archive :)


even more better flaming pedanticism!


On Oct 15, 2009, at 10:41 PM, Nathan Vander Wilt wrote:


Ouch. So the following pattern is incorrect?


Yes;  it is incorrect.


NSError* internalError = nil;
(void)[foo somethingReturningBool:bar error:internalError];
if (internalError) {
  // ...
}


Specifically, assuming anything about the value of 'internalError'
without first determining the return value of -
somethingReturningBool:error: returned a value indicating an error
(typically NO/0/nil/NULL) is an error.


The specific issue is failing to check the return value of the method  
before touching the internalError value.  You MUST check it.


However, the documentation also encourages not assigning nil to local  
NSError* declarations.  Not initializing locals is imho,  
professionally, realistically, and morally wrong.  It's just a bug  
waiting to happen.  And you have to know it is, just looking at it.   
Whatever might have been saved / gained by not initializing them was  
wasted, for all of time, the first time I had to debug the segfault.   
Which I did, like an idiot, a long time ago.


Let me just say I really especially appreciated the time spent  
debugging other people not initializing their locals.  It wasn't  
visions of sugar plums.


Other people have different perspectives on local variable  
initialization.  Wrong perspectives, but different.  Fortunately now,  
they waste their arguments upon the merciless http://llvm.org/img/DragonFull.png 



- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: A good Obc-C framework for sending email?

2009-10-16 Thread Ben Haller

On 16-Oct-09, at 3:04 PM, Alastair Houghton wrote:


On 16 Oct 2009, at 03:54, Andrew Farmer wrote:


On 15 Oct 2009, at 13:34, Ben Haller wrote:
Hi all.  I need a good Obj-C framework for sending email.  I used  
to use the Message.framework associated with Apple's Mail, but  
they killed that a long time ago, sadly.  Then I used Pantomime;  
but it seems to also be abandoned, now, and it is crashing on 10.5  
(and it was never terribly reliable anyway).  Does anybody know of  
a good replacement?  I haven't had any luck trying to find one  
using Google.


Keep in mind that many users may not have any SMTP server  
configured -- an increasing number of users use webmail for  
everything, and don't have a desktop client set up. And, in many of  
these cases, they may be behind a firewall or ISP that blocks  
connections to port 25 (SMTP) on all servers other than their own.  
If you need to reliably deliver email from a user's machine, you'll  
probably need to set up a gateway of some sort yourself, or have  
them input SMTP settings manually.


Or you could do what we do and ask their mail client to deliver it  
for us.  The code we use for that is Open Source, and you can get it  
here:


 http://www.coriolis-systems.com/opensource/

CSMail can also generate messages and pop them up in their client  
ready for them to send themselves, which is something we use in some  
circumstances as well.


(It's possible that we have updated CSMail a bit since the version  
on that page, I don't know... but if someone's interested in using  
it, I can check.)


  I am definitely interested in using it, Alastair.  This solution  
would in fact be optimal for my purposes.  If you could make sure it's  
up to date, that would be great.


Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


A good Obc-C framework for sending email?

2009-10-15 Thread Ben Haller
  Hi all.  I need a good Obj-C framework for sending email.  I used  
to use the Message.framework associated with Apple's Mail, but they  
killed that a long time ago, sadly.  Then I used Pantomime; but it  
seems to also be abandoned, now, and it is crashing on 10.5 (and it  
was never terribly reliable anyway).  Does anybody know of a good  
replacement?  I haven't had any luck trying to find one using Google.


  Jens Alfke suggested wrapping a call to sendmail in NSTask, while  
somehow groping out the right SMTP settings from Mail's prefs, but  
that sounds like quite a hassle, and hard to get really right such  
that emails would be reliably delivered.  Does anybody have reusable  
code to do something along these lines?


  If no good replacement exists, then: if there is anybody on this  
list who knows Pantomime's code, it could very much use an update.  I  
will be happy to supply crash logs.  :-


  Thanks!

Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: A good Obc-C framework for sending email?

2009-10-15 Thread Ben Haller

On 15-Oct-09, at 4:57 PM, Bryan Matteson wrote:


Perhaps EDMessage?

http://www.mulle-kybernetik.com/software/EDFrameworks/


  EDMessage looks good, thanks!

Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


GC crash due to being naughty

2009-10-15 Thread Ben Haller
  Hi all.  I'm getting a crash in auto_zone_root_write_barrier() that  
I don't understand.  I suspect it has to do with this little blurb in  
the Garbage Collection Programming Guide:


Limitations on Mac OS X v10.5:  You may pass addresses of strong  
globals or statics into routines expecting
pointers to object pointers (such as id* or NSError**) only if they  
have first been assigned to directly, rather
than through a pointer dereference. You should never take the address  
of a weak global, static or instance
variable, as assigning or reading through that pointer will bypass the  
weak barriers and expose your programs

to race conditions.

  But I'm not really sure.  :-  Here's the situation.  My app  
generates floods of instances of an NSObject subclass called  
AKIndividual.  So many, in fact, that I don't want to alloc and  
dealloc them all, as that just thrashes the allocator madly (as  
verified with Sampler).  Instead, I want to allocate a pool of them,  
and then throw them in the pool when I'm done with them, and get new  
ones out of the pool.  (When I reuse them, I don't call -init again, I  
just wipe the ivars I'm using and put new values in, which I believe  
is OK.)  When I'm messing about with them, and when they're in the  
pool, I don't want to keep them in Cocoa collections like  
NSMutableArray, because again that introduces too much overhead.   
Countless billions upon billions of these little guys I'm making, and  
the runtimes of my app will be measured in days to weeks, so  
optimizing this bottleneck really is important.


  So my solution was to keep pointers to them in malloced buffers  
instead.  The unused pool is a malloced buffer, the pools of ones  
that are doing various things are also malloced buffers, and  
everything is nice fast C code at this level.  But I guess pointers to  
objects kept in malloced buffers are weak references, so my objects  
would be collected if I didn't have a strong reference somewhere.  So  
when I first allocate them, I throw them into an NSMutableArray, and I  
don't ever take them out.  That array is kept by the controller of the  
whole shebang; so when that controller gets collected, then all the  
individuals will be collected, but until then, they should always be  
strong-referenced.


  This seems like it ought to work; and yet I get that crash in  
auto_zone_root_write_barrier().  After some puzzling, I found the  
above paragraph in the GC guide.  I am indeed on 10.5.  Is this what's  
biting me?  I guess all the pointers to my AKIndividuals that are kept  
in my malloced arrays are all weak references, and so I guess the  
pointer to the malloced array itself, for example, is a pointer to a  
weak reference such as I am not supposed to use, and whenever I do  
something like individuals[i] to get an instance from my malloced  
buffer I guess I'm violating the weak barriers.  I find it hard to  
believe that I'm not allowed to keep an array of pointers to objects,  
though; is that really what this blurb is saying?  (On the other hand,  
the GC guide also says that the malloc zone is never scanned, which  
would imply that this is fine, and that the references I put in my  
malloced arrays are not even weak; but then I'm puzzled by the crash  
in a write barrier function...)  I don't really understand what is  
prohibited and exactly why; that blurb is way too short, and the  
example is too short and cryptic.  Can some explain what is actually  
prohibited, and why, and whether what I'm doing is prohibited?


  Given the architecture I'm aiming for, I don't need the references  
to even be weak references; I don't need them to zero out, because  
they never will, because these AKIndividuals live at least as long as  
any given malloced array of them will live.  Indeed, I don't care  
about GC on them at all; I'd be quite happy to exclude them from the  
GC scheme altogether, and get back the overhead of these read/write  
barriers, given how much thrash is involved with them.  Is that  
possible?  For example, can I malloc the instances of AKIndividual  
myself out of the malloc zone to exclude them from GC, or is that a  
Bad Idea?


  Sorry for the long email.  Comments?

Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: GC crash due to being naughty

2009-10-15 Thread Ben Haller
  That looks like it is more a matter of decreasing memory usage than  
decreasing alloc/dealloc/containment overhead.  A flyweight is an  
object that minimizes memory use by sharing as much data as possible  
with other similar objects; it is a way to use objects in large  
numbers when a simple repeated representation would use an  
unacceptable amount of memory.  So I don't think it applies to my  
problem.

  Thanks though!

Ben Haller
Stick Software


On 15-Oct-09, at 7:14 PM, Oftenwrong Soong wrote:


Hi Ben,

Have you considered the so-called Flyweight design pattern? It is  
designed to solve the problem of having a zillion objects to  
allocate. It sounds like this pattern might prevent your having to  
play the dirty tricks that are causing you problems.


In the frameworks, Flyweight is used, AFAIK, in NSNumber, NSCell,  
and other classes. There's a good description of the pattern here:

http://en.wikipedia.org/wiki/Flyweight_pattern

Hope this helps a little. (I don't know what could be done to solve  
the crash you describe but passing pointers as you described sounds  
like it's bound to cause nasty problems.)


Soong



- Original Message 
From: Ben Haller bhcocoa...@sticksoftware.com
To: Cocoa List cocoa-dev@lists.apple.com
Sent: Thu, October 15, 2009 3:54:11 PM
Subject: GC crash due to being naughty

 Hi all.  I'm getting a crash in auto_zone_root_write_barrier() that  
I don't understand.  I suspect it has to do with this little blurb  
in the Garbage Collection Programming Guide:


Limitations on Mac OS X v10.5:  You may pass addresses of strong  
globals or statics into routines expecting
pointers to object pointers (such as id* or NSError**) only if they  
have first been assigned to directly, rather
than through a pointer dereference. You should never take the  
address of a weak global, static or instance
variable, as assigning or reading through that pointer will bypass  
the weak barriers and expose your programs

to race conditions.

 But I'm not really sure.  :-  Here's the situation.  My app  
generates floods of instances of an NSObject subclass called  
AKIndividual.  So many, in fact, that I don't want to alloc and  
dealloc them all, as that just thrashes the allocator madly (as  
verified with Sampler).  Instead, I want to allocate a pool of them,  
and then throw them in the pool when I'm done with them, and get new  
ones out of the pool.  (When I reuse them, I don't call -init again,  
I just wipe the ivars I'm using and put new values in, which I  
believe is OK.)  When I'm messing about with them, and when they're  
in the pool, I don't want to keep them in Cocoa collections like  
NSMutableArray, because again that introduces too much overhead.   
Countless billions upon billions of these little guys I'm making,  
and the runtimes of my app will be measured in days to weeks, so  
optimizing this bottleneck really is important.


 So my solution was to keep pointers to them in malloced buffers  
instead.  The unused pool is a malloced buffer, the pools of ones  
that are doing various things are also malloced buffers, and  
everything is nice fast C code at this level.  But I guess pointers  
to objects kept in malloced buffers are weak references, so my  
objects would be collected if I didn't have a strong reference  
somewhere.  So when I first allocate them, I throw them into an  
NSMutableArray, and I don't ever take them out.  That array is kept  
by the controller of the whole shebang; so when that controller gets  
collected, then all the individuals will be collected, but until  
then, they should always be strong-referenced.


 This seems like it ought to work; and yet I get that crash in  
auto_zone_root_write_barrier().  After some puzzling, I found the  
above paragraph in the GC guide.  I am indeed on 10.5.  Is this  
what's biting me?  I guess all the pointers to my AKIndividuals that  
are kept in my malloced arrays are all weak references, and so I  
guess the pointer to the malloced array itself, for example, is a  
pointer to a weak reference such as I am not supposed to use, and  
whenever I do something like individuals[i] to get an instance  
from my malloced buffer I guess I'm violating the weak barriers.  I  
find it hard to believe that I'm not allowed to keep an array of  
pointers to objects, though; is that really what this blurb is  
saying?  (On the other hand, the GC guide also says that the malloc  
zone is never scanned, which would imply that this is fine, and  
that the references I put in my malloced arrays are not even weak;  
but then I'm puzzled by the crash in a write
barrier function...)  I don't really understand what is prohibited  
and exactly why; that blurb is way too short, and the example is too  
short and cryptic.  Can some explain what is actually prohibited,  
and why, and whether what I'm doing is prohibited?


 Given the architecture I'm aiming for, I don't need the references  
to even be weak references

Re: GC crash due to being naughty

2009-10-15 Thread Ben Haller

On 15-Oct-09, at 7:30 PM, Greg Parker wrote:

A pointer value stored in an ordinary malloc block is neither a  
strong nor a weak reference. It is a dangling pointer. It can be  
used safely, but requires great care because the garbage collector  
has no knowledge of what you're doing.


The auto_zone_root_write_barrier() crash can occur when you take the  
address of a global variable, then store into the global indirectly  
via that address. What does the crashed line of code look like?


  OK, here's a bit of context.  The backtrace:

#0  0x95058d7b in auto_zone_root_write_barrier ()
#1  0x964e40a8 in objc_assign_strongCast_gc ()
#2  0x7198 in -[AKPopulation addIndividualsFromPopulation:]  
(self=0x102b740, _cmd=0xe76c, population=0x10a9250) at .../ 
AKPopulation.m:101


  That method:

- (void)addIndividualsFromPopulation:(AKPopulation *)population
{
UInt32 individualCountForPop = [population individualCount];
AKIndividual **individualsForPop = [population individuals];
int i;

if (individualCount + individualCountForPop  individualCapacity)
{
individualCapacity = (individualCount + individualCountForPop) 
* 2;

		individuals = realloc(individuals, individualCapacity *  
sizeof(AKIndividual *));

}

for (i = 0; i  individualCountForPop; ++i)
individuals[individualCount++] = individualsForPop[i];
}

  The crash is in the last line of the method, in the assignment.
  The class as it stands right now:

@interface AKPopulation : NSObject
{
NSString *title;

UInt32 individualCount;
UInt32 individualCapacity;
AKIndividual **individuals; // malloc'ed array of 
AKIndividual *
}

@property (readwrite, copy) NSString *title;
@property (readonly) UInt32 individualCount;
@property (readonly) AKIndividual **individuals;

...
@end

  So the intent of the method is just to bulk-add individuals from  
one population into another population.


  Perhaps another way to ask the question is: suppose you wanted to  
implement a new collection class, akin to NSMutableArray but somehow  
different.  How would you safely do it under GC, without using any of  
the pre-made Cocoa collections internally?  That's all my AKPopulation  
really is: a poor man's (but a speedy man's!) re-implementation of  
something like NSMutableArray.  Ought to be possible, right?  So how  
do I manage this write barrier business to make it work properly?


Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: GC crash due to being naughty

2009-10-15 Thread Ben Haller

I'd start by taking a look at the CHDataStructures framework:  
http://cocoaheads.byu.edu/wiki/chdatastructures

It's a framework hosted by our local CocoaHeads group that includes  
most of the data structures that Apple forgot.  =)


  An interesting framework, looks useful.  Looking at the  
CHAbstractCircularBufferCollection class, I don't see it doing any  
special GC-related dance.  The only substantial differences between it  
and what I am doing are that:


- I use malloc to make my array of pointers to objects, and it uses  
NSAllocateCollectable with NSScannedOption


- I declare my pointer as AKIndividual **individuals and it uses  
__strong id *array


  So perhaps those choices avoid the issue, by avoiding the caveat  
You should never take the address of a weak global, static or  
instance variable, as assigning or reading through that pointer will  
bypass the weak barriers and expose your programs to race  
conditions.  But then as Greg Parker said, references stored in a  
malloced block are neither weak nor strong, they are just dangling  
pointers.  So I don't really understand why I'm getting bitten in the  
first place.  Dangling pointers is exactly what I want; why is  
auto_zone_root_write_barrier() getting into the middle of my  
assignment loop in the first place?


Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: GC crash due to being naughty

2009-10-15 Thread Ben Haller

On 15-Oct-09, at 8:10 PM, Oftenwrong Soong wrote:


Hi Ben,

You say the crash occurs in this line:

   individuals[individualCount++] = individualsForPop[i];

The problem may be in the post-increment (individualCount++). IIRC,  
there is no agreed-upon compiler standard as to whether the post- 
increment will occur before or after the assignment. It is possible  
that you're using the bytes after the end of the array as a pointer,  
which points to a random location rather than to your desired data.  
If you want the increment to happen after the assignment, do this:


   for (i = 0; i  individualCountForPop; ++i) {
   individuals[individualCount] = individualsForPop[i];
   individualCount++;
   }

If you want it before, just reverse the order of the two lines.

I've had many a headache in the past with things like this!!


  Huh.  Could've sworn that was well-defined.  Well, I've been away  
from coding for about six years now, guess I've gotten a little rusty.
  In any case, this change does not fix the problem; same crash, on  
the assignment line.


Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: GC crash due to being naughty

2009-10-15 Thread Ben Haller

On 15-Oct-09, at 8:26 PM, Greg Parker wrote:

I don't see any global pointer variables involved. My guess is that  
`individuals` is uninitialized or NULL or  
`individuals[individualCount]` is out of bounds. The write barrier  
objc_assign_strongCast() does range checks on the destination  
address, and will fall back to auto_zone_root_write_barrier() for  
addresses it doesn't recognize. Those include malloc blocks, global  
variables, and bogus addresses.



Perhaps another way to ask the question is: suppose you wanted to  
implement a new collection class, akin to NSMutableArray but  
somehow different.  How would you safely do it under GC, without  
using any of the pre-made Cocoa collections internally?  That's all  
my AKPopulation really is: a poor man's (but a speedy man's!) re- 
implementation of something like NSMutableArray.  Ought to be  
possible, right?  So how do I manage this write barrier business to  
make it work properly?


You need to ensure two things when implementing storage for GC  
pointers. First, the storage must be scanned by the garbage  
collector. Second, writes to the storage must use an appropriate  
write barrier function...


  This all makes sense to me, to the extent that I understand write  
barriers at all.  :-


  I switched my code over to NSAllocateCollectable with  
NSScannedOption, and it still crashed.


  This led me to generate a new hypothesis: that I am an idiot.  I  
have now proven that hypothesis to my full satisfaction.  I will not  
be telling the list what the error was that caused my code to crash.   
Let's just say I'm very out of practice at this whole coding thing,  
and leave it at that.  :-


  Still, this thread was quite useful in that it did solidify my  
understanding of weak/strong/dangling, and led me to switch my  
collection class over to strong references.  That's progress.  Thanks  
to everybody for their help!


Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Default Core Data errors

2009-10-14 Thread Ben Trumbull
Do you check, and at least assert, if any API that has an NSError**  
parameter returns one ?  (typically a return value of NO or nil).  For  
Core Data, you'll always want to check adding a store to the  
coordinator, saving, and fetching.  For your documented based app, the  
NSDocument APIs can also return errors.


When you get an NSError, you'll want to also log its userInfo  
dictionary.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: CoreData could not fulfill a fault after Save As

2009-10-14 Thread Ben Trumbull

The short description is this - I have a document based CoreData app.
I can carefully craft a set of data. I then open the document, select
a particular record, and do a Save As. This works fine. But when I
select a second record, I get errors that CoreData could not fulfill a
fault. If I quit the app and re-launch it, I can operate on the copy I
just saved w/o issue, so apparently the data is there. I haven't a
clue what the problem is.


Does your app run correctly on 10.5.* ?  There's a known regression  
similar to this in 10.6.0 and 10.6.1.


If this reproduces on a system other than 10.6.0 or 10.6.1, please  
file a bug.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Default Core Data errors

2009-10-14 Thread Ben Trumbull


On Oct 14, 2009, at 12:21 PM, Rick Mann wrote:

In the simplest case, I don't create any entities. I don't override  
any of NSPersistentDocument's persistence-related methods. I just  
save the new untitled document, then try to re-open it.



You can override the methods declared in NSPersistentDocument.h  
particularly configurePersistentStoreCoordinatorForURL and  
readFromURL, and just call super.  But look at the BOOL result and if  
NO, the NSError.


You can also grab the error in the debugger as others have suggested.

- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Screensaver won't run on 10.6 even after porting to 64-bit

2009-10-13 Thread Ben Haller

On 12-Oct-09, at 8:14 PM, Charles Srstka wrote:


On Oct 11, 2009, at 9:46 PM, Ben Haller wrote:

Most of the bugs I had to fix were related to either using long  
instead of int, or needing a -finalize method.


You should actually probably be using NSInteger instead of either of  
those these days.


  Yes, but NSInteger is 10.5 or later; I'm keeping 10.4 compatibility  
for now.  Anyhow, those uses were all in my own internal logic, which  
can stay using 32-bit ints.


There's actually a ConvertCocoa64 script found in /Developer/Extras/ 
64BitConversion that will scan your files for other things that  
could bite you in the transition to 64-bit. You should probably give  
it a spin, to make sure you're all up to date.


This page contains some handy information, too:

http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Cocoa64BitGuide/ConvertingExistingApp/ConvertingExistingApp.html


  Good stuff, I'll check it out.  Thanks Charles!

Ben Haller
Stick Software


___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: More Core Data Questions

2009-10-13 Thread Ben Trumbull


On Oct 13, 2009, at 3:17 AM, Jon Hull wrote:

You don't need proxies or NSProxy for this.  You can just use a  
delegate.  Off the cuff, I might consider implementing a protocol  
on your immutable objects for methods like currentLocation and  
currentPlayer which vector through a semi-global context object  
not unlike the app delegate.  Then you can use keypaths to  
naturally write currentPlayer.name and so forth.  NSProxy is  
unnecessarily heavy weight for simple delegation.  They use memory  
too, ja know.  And the semi-global context allows you to avoid  
making all your objects larger.  You might even model the current  
state as a formal entity.  That buys you change tracking, undo,  
multi-writer conflict resolutions and the ability to easily  
persistent and search for it.  It also allows other managed objects  
to work with it naturally.
Hmm... something to consider.  The proxies do allow some powerful  
runtime state effects.  The currentLocation was just a simple (and  
often used) example, but it is easy to have proxies which represent  
The sister of the person I am currently talking to or the location  
of that person or the item which that person holds in their hand.   
They can also be used to represent groups of characters.  This is  
very powerful, and has come in very useful.  Still, it might be  
possible to get the same functionality in another way.


Okay.  Typically the Cocoa way of doing that is by name and using  
keypaths instead of by pointer value and NSProxy.


and then call off  to the manager with the id whenever they need  
to run an event.  Inside
the manager I would either call off to a small sql database with  
blobs

holding freeze-dried (keyedArchiving) objects  an id column,


not a great plan.  No searching into blobs, no partially loading or  
saving the larger freeze dried objects.
hmm...  The largest blob would probably be an object with an array  
of 20 or so pointers/ids.  Not sure I need to search into them...  
mostly I just need to grab them by id.


I had considered just using core data for everything, but as I  
mentioned in a previous post, I *need* to have consistently ordered  
arrays of these immutable objects (which can be in multiple places  
in a single array, and can be in multiple arrays).  This is  
apparently difficult using core data :-(


It's not difficult, although it is a bit tedious.  Ordered  
relationships require you model the join table between two entities  
yourself (for many-to-manys), and add an ordering attribute.  For one- 
to-many, you can put the ordering attribute on the destination entity  
(no join table necessary).


Although, now that I think about it, perhaps I can store *just* the  
array of ids as a binary property, and have everything else defined  
in the entity.  I will have to do some experiments.


Yes, you could do that.


Also, you could do that trivially with Core Data and just be done.
Do you mean store the blobs in a core data managedObject instead of  
a SQL database?


yes


or avoid the blobs entirely using core data?


Probably

Unfortunately, it sounds like you don't have a ready alternative  
besides to spend a considerable amount of your own engineering  
resources.  You'll have to decide if learning Core Data, and tuning  
your app performance fits within your schedule requirements, and  
whether implementing, debugging, and tuning all this yourself will  
really take any less time.


You might consider mocking up a Core Data version over a few days  
and seeing how far you get.


Yes, I think I will try that.

Any advice on how to handle the 2 different types of graphs  
mentioned in my earlier post?  Ideally I should have 2 files. One  
holding the event tree and one holding the rest (i.e. the stuff that  
changes).  They main problem there is that they have connections  
between each other (e.g. an event might take a location or character  
as a parameter)



Just create two stores and add them to the same  
NSPersistentStoreCoordinator.  The connections between them can be  
represented via keypaths (bound dynamically) or persistently by  
stashing the objectID's URI away and materializing it in a transient  
relationship in -awakeFromFetch


- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Saving for iPhone - Can core data handle this?

2009-10-12 Thread Ben Trumbull

Jon,

Your question is a bit amorphous.  Can Core Data do something like  
this ?  Sure.  May it require adjusting things to fit into its  
architecture ?  Possibly.



I have a game project for the iPhone which has a rather complicated
object graph


Well, it would probably only take a few minutes to mock something up  
in the model editor in Xcode.  That would help make your question more  
concrete.



There is a large graph of tiny immutable objects which represent the
story (including different branches of the storyline).


How tiny is tiny ?  People have widely different ideas about tiny  
and huge and the difficulties of various problems.



This graph is
large enough that I only want to keep the nodes that are actually
being used in memory.


100 objects ?  1,000 ?  100,000,000 ?  The largest db in a deployed  
iPhone app using Core Data that I know of is about 450,000 rows.  (FDA  
warning: results not typical)



There is also a separate graph of game objects
(characters, etc...) that change state over time and will need to be
saved as part of a saved game.  These seem like they should be stored
separately since one never changes and will be common for all players,
while the other is different for each player.  I also want to be able
to get a fresh copy of the changing objects for new games.


Is this for local or remote data ?


The final complication is that I have several proxies being used in an
important way, and I don't think there is any NSProxy equivalent for
NSManagedObject.  I guess I would just have to hope that
NSManagedObject doesn't have any methods that the targets of the proxy
override.


Uhm...  Why ?  I don't think NSManagedObject will be happy with  
NSProxy and vice versa.  I'd recommend against this.  If you need to  
use NSProxy for something else, then I'd recommend adding an observer  
to the NSManagedObjectContext and proxying your custom observer.  Or,  
you can use composition to create your own object that has an  
NSManagedObject || NSManagedObjectID ivar and then proxy that.



I have been reading the docs for Core Data, and have a rough idea on
how I might accomplish all of this, but I wanted to see if someone had
experience with this and could keep me from spending time going down
the wrong path if it isn't going to work.

So, do you think core data can handle this?  What approach (roughly)
should I use?


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: CoreData Bug? (SQLite vs XML) + isolated reproducible case

2009-10-12 Thread Ben Trumbull
Thanks for the test project.  However, reviewing and fixing all  
compiler warnings is likely to make development a significantly less  
frustrating experience.  We've taken to fixing (nearly) all compiler  
warnings, even ones we know are harmless, so we can easily find the  
new ones that likely aren't.  A lot of people like -Werror for exactly  
this reason, but that's a bit too draconian for my taste.



CoreDataBug_DataModel.xcdatamodel:SmartFolder.sources: warning:  
SmartFolder.sources -- to-many relationship does not have an inverse:   
this is an advanced setting (no object can be in multiple destinations  
for a specific relationship)


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: More Core Data Questions

2009-10-12 Thread Ben Trumbull

Ok, let me ask some more specific questions and see if that gets a
response...  Feel free to respond if you only know the answer to 1 or
2 of these.

1) Can I count on a to-many relationship keeping the order of the
managedObjects it points to?  The order is very important in this
case, and I need a way to ensure that the order does not change when
the object is saved and reloaded.


No.  You'll have to model order as an attribute yourself.


2) Does core data require a run-loop to work?


No.


3) What is the best way of connecting objects from different stores?
I am considering giving them UUIDs and then storing that as a
reference.  Then setting a transient property based on that in -
awakeFromFetch.  Alternatively, I could store it as a fetched
property, but I want it to be a 1:1 correspondence.


That's fine, although you can just use the URI representation of the  
destination object instead of creating your own separate UUID.  You  
might look at /Developer/Examples/CoreData/iClass



4) Is there a better way to get this lazy loading?


What was the first way ?


 My main goal is to
keep only those objects from this large (1000) object graph in memory
that are needed (since the iPhone has limited memory).


You may find the NSFetchedResultsController useful, as well as the  
options on NSFetchRequest like -setFetchBatchSize:  They are very  
aggressive about memory optimizations.



Basically, I
want the behavior of the old resource manager from the olden days
(that is I can act as if my full object graph is in memory, but only
those that are needed actually are... and they are fetched just in
time).


Core Data always does that.  That's the default with its SQLite  
persistent store.


Are you making this more complicated than it needs to be for  
performance issues you have yet to measure ?  I wouldn't add multiple  
stores to work around a performance issue before actually trying it.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: More Core Data Questions

2009-10-12 Thread Ben Trumbull
 bringing  
a previously designed project to deployment .  Major changes in  
technologies are generally best saved for major versions.  Also known  
as the if it's making money, don't  with it principle.


Unfortunately, it sounds like you don't have a ready alternative  
besides to spend a considerable amount of your own engineering  
resources.  You'll have to decide if learning Core Data, and tuning  
your app performance fits within your schedule requirements, and  
whether implementing, debugging, and tuning all this yourself will  
really take any less time.


You might consider mocking up a Core Data version over a few days and  
seeing how far you get.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Screensaver won't run on 10.6 even after porting to 64-bit

2009-10-11 Thread Ben Haller
  Hi folks.  So my screensaver broke on 10.6, along with everybody  
else's, and I'm told that's because it has to be compiled for the 64- 
bit architecture, because System Prefs is a 64-bit app on 10.6.  So I  
set up a conditional compilation thing where it compiles three versions:


- ppc against the 10.4 SDK (deployment target 10.4), GCC 4.0
- intel against the 10.4 SDK (deployment target 10.4), GCC 4.0
- intel 64-bit against the 10.6 SDK (deployment target 10.6), GCC 4.2

  These settings are from a web page about how to get a screensaver  
to work on 10.6; I don't know why the GCC version needs to vary, for  
example.  I'm just following orders.  :-
  This all seems to work fine, after much fussing about with  
deprecated APIs and such.  My screensaver now builds and links without  
errors, and lipo gives me promising-looking output showing my three  
architectures.  The screensaver runs fine on 10.5 intel; haven't tried  
it on 10.4 or ppc, but I imagine it's fine there too.


  But on 10.6 I still get the same error from System Preferences.   
Opened Console and saw this:


10/11/09 2:51:18 PM	ScreenSaverEngine[204]	Error loading ...:   
dlopen(..., 265): no suitable image found.  Did find:

...: GC capability mismatch
10/11/09 2:51:18 PM	ScreenSaverEngine[204]	ScreenSaverModules: can't  
get principalClass for ...


  So I guess System Preferences doesn't like my garbage collection  
setting (which is set to Unsupported).  Do I really need to turn GC  
on to get my screensaver to work??  I haven't seen anything about that  
elsewhere, so this catches me a bit off guard.  I would have assumed  
that they would build it to be able to handle either style.
  Is there any way around this?  Since I want my screensaver to still  
run on 10.4, this is more than a little inconvenient.


  Thanks for any advice!

Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Screensaver won't run on 10.6 even after porting to 64-bit

2009-10-11 Thread Ben Haller

On 11-Oct-09, at 3:28 PM, Clark Cox wrote:

On Sun, Oct 11, 2009 at 12:23 PM, Dave Keck davek...@gmail.com  
wrote:
 So I guess System Preferences doesn't like my garbage collection  
setting
(which is set to Unsupported).  Do I really need to turn GC on  
to get my

screensaver to work?


Yes, your screensaver must be GC-supported to support Snow Leopard.
This bit me recently too - I wasn't expecting it either. So much for
GC making our lives easier, eh? :)

On the bright side, you can make your bundle GC-supported, which  
means

it contains both retain/release and GC logic. This will at least buy
you 10.5  10.6 support in the same bundle, but I imagine you'll have
to compile a separate GC-unsupported version for 10.4, but I'm really
not sure. Hopefully someone else could comment on that.


You can use per-arch build settings to make the ppc and i386 parts
GC-unsupported, but make the x86_64 part GC-required; there's no need
to build separate bundles.


  OK, makes sense.  My only question: what's the best way to switch  
at compile time based on whether GC is enabled for the build?  I.e.  
what do I #if or #ifdef?  I could do it based on the arch or the SDK,  
but if there's a flag specifically for GC I'd rather use that...

  Thanks!

Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Screensaver won't run on 10.6 even after porting to 64-bit

2009-10-11 Thread Ben Haller

On 11-Oct-09, at 3:52 PM, Kyle Sluder wrote:

On Oct 11, 2009, at 12:44 PM, Ben Haller  
bhcocoa...@sticksoftware.com wrote:


OK, makes sense.  My only question: what's the best way to switch  
at compile time based on whether GC is enabled for the build?  I.e.  
what do I #if or #ifdef?  I could do it based on the arch or the  
SDK, but if there's a flag specifically for GC I'd rather use that...


The purpose of GC-supported rather than GC-required is that you  
don't do this. Rather, you write your code so that it works in  
either retain-release or garbage collected environments.


  Yes, but my code also needs to compile as GC-unsupported against  
the 10.4 SDK, where any GC-specific calls that I might need to make  
will not compile.  Am I missing something?


Ben Haller
Stick Software


___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Screensaver won't run on 10.6 even after porting to 64-bit

2009-10-11 Thread Ben Haller

On 11-Oct-09, at 4:11 PM, Kyle Sluder wrote:

On Oct 11, 2009, at 1:06 PM, Ben Haller  
bhcocoa...@sticksoftware.com wrote:


Yes, but my code also needs to compile as GC-unsupported against  
the 10.4 SDK, where any GC-specific calls that I might need to make  
will not compile.  Am I missing something?


Do you really need to compile against the 10.4 SDK? Why not compile  
against the 10.6 SDK with a 10.4 deployment target?


  I frankly don't know.  I'm following the instructions I found  
telling me what build settings would result in a screensaver that  
would run on 10.4 through 10.6, ppc and intel:


http://www.eisbox.net/2009/09/01/2402-distributing-a-screen-saver-for-10-4-10-5-and-10-6/

  I saw similar instructions on several other web pages.  I've got my  
screensaver successfully compiling and running for everything except  
10.6, so I'm loath to go back and mess around with this stuff now.  I  
presume the author had a good reason for specifying the 10.4 SDK and  
GCC 4.0 for the older archs.  Perhaps the 10.6 SDK is not supported  
for PPC builds, or something?  I have no idea.  I'm very new to all  
this (I've been away from Cocoa programming for about five years), and  
I'm finding the learning curve to be a bit steep.


If you don't need the NS/CFMakeCollectable or other GC-specific  
functions (which most usually don't) then it's a moot point.


  Well, I imagine I'm going to need to use *something* GC-specific --  
strong/weak declarations, finalize methods, whatever.  At present my  
screensaver crashes on 10.6 when compiled with GC-supported set.  That  
is presumably because some object is getting collected prematurely.   
I'll need to make some change to the code to fix that, and that change  
may not be compatible with the non-GC builds, since it will use APIs  
or Objective-C 2.0 syntax that is not available when building for 10.4  
PPC.  This is a large project (for a screensaver), with many classes,  
and runs multithreaded.  The idea that I can make it compile both GC- 
unsupported and GC-supported without a single #if seems unlikely.  I  
may well be completely misunderstanding something; but having read  
through the Garbage Collection Programming Guide several times now, I  
don't see any particular reason to think that I won't need GC-specific  
calls.  They certainly give lots of examples of cases in which one does.


  Sorry if I'm just being clueless, but I'm trying hard to get a  
clue.  :-


Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Screensaver won't run on 10.6 even after porting to 64-bit

2009-10-11 Thread Ben Haller

On 11-Oct-09, at 5:28 PM, Clark Cox wrote:


On Sun, Oct 11, 2009 at 1:55 PM, Ben Haller
bhcocoa...@sticksoftware.com wrote:

 Well, I imagine I'm going to need to use *something* GC-specific --
strong/weak declarations,


Not likely.


finalize methods, whatever.


Implementing finalize methods are actually quite rare; and even if you
do implement them, that won't prevent building for/running on 10.4.


  I see that -finalize was available on 10.4 even though GC didn't  
arrive until 10.5, so I would be able to call [super finalize].  I  
guess Apple was planning ahead.  :-



It's exceedingly unlike that whatever change you need to make will
render the code incompatible with 10.4.
...
Perfectly understandable. I'm just trying to assure you that the cases
in which you actually have to call GC-specific API is quite small, and
are usually relegated to edge-cases.


  OK.  Well, I guess I'll wait and see what changes I need to make to  
support GC before I worry about this further.  (See the post I'm about  
to send in.  :- )


  Thanks!

Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: [iPhone} Exception After Creating First Object

2009-10-10 Thread Ben Trumbull

I got a couple of private messages about breakpoints and
stacktraces, which, of course, I had done before I posted my
question.  That's how I discovered that [mod
processPendingChanges] led to an exception when adding to an
empty database table.

I learned a little more about the exception.  It occurs in
[self.tableView endUpdates] which is  invoked, I think, as a
result of [moc processPendingChanges].

I have had problems in the past with [self.tableView endUpdates]
with empty database tables but thought that this time was
different.  Previously, I had tried preventing [self.tableView
endUpdates] being called when the database tables was empty but
that caused other problems (e.g. my Add Entity Name button
didn't appear when the database table was empty).

I've seen others mention problems with [self.tableView
endUpdates].  Does anyone know how to make [self.tableView
endUpdates] less vulnerable when the associated database table
is empty?


Steve,

Which version of iPhoneOS SDK are you building for ?  This sounds like  
an issue that was fixed in 3.1.  There has been more discussion of  
known issues and work arounds for the NSFetchedResultsController on  
the devforums.  You might try searching them, or looking at  https://devforums.apple.com/message/100783#100783 



- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: CoreData async fetch request

2009-10-08 Thread Ben Trumbull


On Oct 7, 2009, at 10:12 PM, David Melgar wrote:


Hello,
I didn't mean to state threads as a requirement when I said async,  
I just meant some way to get partial results, such as a call to a  
delegate I referenced in the previous note. And I'm certainly not  
seeking complexity of threads if I don't need it.


There isn't a simple way to do this.  There is, however, a simple way  
to make your queries (in both Core Data, and direct SQLite) 100x faster.


In my case, == is not the query I need. I really want case  
insensitive match as I presumed LIKE would do, or better yet, 'LIKE  
foo%'.


Great.  The Derived Property sample project on ADC shows you exactly  
what you need to do for replacing LIKE foo or LIKE foo%



In the meantime, I've just completed a test using SQLite.
The query in Coredata using 'LIKE foo%bar' across roughly 8 million  
records didn't return anything until the query was done, and the  
query took 2min 14sec,


This runs through ICU, and cannot use an index.  It can trivially be  
made 100x faster, at least for equality, prefix, and suffix matching.


What's the actual SQL Core Data logs ?

Doing what I interpreted to be equivalent using SQLite across 20  
million records returned in 11 seconds


What was the actual SQL you believed equivalent ?

and I was able to get my first result almost immediately without  
needing threads. They provide a callback scheme, analogous to  
calling a delegate in Cocoa. FYI, this is across 20 different  
databases, otherwise it may have been faster.


For what I'm doing, SQLite seems much faster, smaller footprint and  
easier to comprehend. I don't understand what I'm losing.


In your note you mention the cost of doing unicode aware regex and  
sorting. As far as I know, I don't need any of those, at least not  
yet.


All of your data is 100% 7 bit ASCII ?  None of your customers will be  
Asian, European, or Hispanic ?  None of your English customers will  
expect Unicode data that they copy and paste into your application  
from Safari to be preserved correctly ?


If your answer is no, then you'll need to implement your own string  
matching operations for SQLite using either CFString or ICU.  SQLite's  
built in operators use memcmp().  Once you've done that, I'd love to  
see the performance results.



I took a brief look at the derived property example. Seems complex.


What about the example seems complex ?  Everything you need is in 1  
file, that's got 107 lines of code.  You can just copy and paste that  
code.  Make a searchText column that has preprocessed the text data  
into a simpler form that can be used with an index and a simpler query.


You say you want to do a case insensitive search across 20 million  
rows.  You could absorb the cost of that, relative to a simple binary  
bitwise compare, for each of the 20 million rows.  And pay it again  
every time you execute a query.   Or, you could store a preprocessed  
column, and absorb that cost for just 1 string, the current search  
term foo


Perhaps for ASCII case insensitivity, that doesn't seem particularly  
interesting.  But once you start dealing with real world text  
encodings, which every Mac OS X and iPhone OS customer expects from  
every app, this becomes a big deal.  Unicode is complex and difficult  
to work with.


Something the framework should give me an option to handle rather  
than me having to generate such complex code. Does it advocate  
creating another field in the database as a normalized version of  
the field I really want to search on?


Yes.


Why would this be better than using SQLite directly?



Doing this in SQLite directly will also be 100x faster than what  
you're doing now.  Regardless of whether or not you decide to use Core  
Data, this would be better.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Core Data KVO with To-Many Relationships

2009-10-08 Thread Ben Trumbull

Since my previous post, I have been able to get the functionality I
was hoping for with the following code in my Department subclass. I
would greatly appreciate some feedback as to whether this is an
appropriate way to implement the functionality or if there is a more
efficient or cleaner way.


KVO doesn't have an easy way to observe a collection's contents, so  
the NSNotification approach is your best bet.



- (void)awakeFromFetch {
   [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(managedObjectContextDidChange:) name:
NSManagedObjectContextObjectsDidChangeNotification object:[self
managedObjectContext]];
}

- (void)awakeFromInsert {
   [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(managedObjectContextDidChange:) name:
NSManagedObjectContextObjectsDidChangeNotification object:[self
managedObjectContext]];
}


Most people use a 3rd object to do this instead of having the  
individual managed objects.  You can have an innocent bystander  
observe the NSManagedObjectContextObjectsDidChangeNotification, see if  
any interesting objects have changed, and then ping them to recompute  
whatever you need.  Much easier to manage registering and  
unregistering observers.



- (void)managedObjectContextDidChange:(NSNotification *)notification {
   // Get a set containing ALL objects which have been changed
   NSSet *insertedObjects = [[notification userInfo]
objectForKey:NSInsertedObjectsKey];
   NSSet *updatedObjects = [[notification userInfo]
objectForKey:NSUpdatedObjectsKey];
   NSSet *deletedObjects = [[notification userInfo]
objectForKey:NSDeletedObjectsKey];

//this method of gathering changed objects is because the final set
was always null if the first set was null
   NSSet *changedObjects;
if([insertedObjects count]  0){
		changedObjects = [insertedObjects  
setByAddingObjectsFromSet:updatedObjects];
		changedObjects = [changedObjects  
setByAddingObjectsFromSet:deletedObjects];

}else{
if([updatedObjects count]  0){
			changedObjects = [updatedObjects  
setByAddingObjectsFromSet:deletedObjects];

}else{
changedObjects = [NSSet setWithSet:deletedObjects];
}
}

if([changedObjects intersectsSet:[self employees]]){
   //if an employee in this department changed, indicate
that the totalSalary attribute should be refreshed
[self willChangeValueForKey:@totalSalary];
[self didChangeValueForKey:@totalSalary];
}   
}


That's the basic idea, but it's easier and faster to do that once, in  
one master observer, than in each managed object.


- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: CoreData async fetch request

2009-10-08 Thread Ben Trumbull


On Oct 8, 2009, at 8:28 PM, David Melgar wrote:

I read a little on ICU and now understand that sqlite by default  
does not handle case insensitive unicode.
Is there an easy way to make sqlite use ICU on the Mac, or do I have  
to build it myself with ICU enabled?


Probably the easiest thing to do (besides just using Core Data) is  
register custom functions with the SQLite API that go through  
CFString.  The SQLite APIs for this are fairly straight forward.  The  
ICU dylib on Mac OS X is not public API.  There are a variety of  
references to building ICU or otherwise addressing this issue on the  
web.  Should you do that, you can register custom functions leveraging  
ICU with SQLite as one would using CFString.  I'd strongly recommend  
against building and statically linking SQLite yourself.


Based on the derived property example, it seems that I would need to  
duplicate any text fields I commonly search on where I want to  
support case insensitive queries.


Yes, for data sets of this size.  For smaller data sets, in the 10^2  
or 10^3 range, you might decide to skip this and accept slower  
queries since they'll probably be around 5ms - 20ms.


How does spotlight manage to index so much text and respond quickly?  
Are those queries can insensitive?


Spotlight supports insensitive queries.  Spotlight also duplicates  
much of the material for its index.  The importing process is not  
free.  You're certainly welcome to put all your data into Spotlight  
and test its query performance for your purposes.  Spotlight is  
fundamentally a full text search index.  It's optimized heavily for  
prefix and word searching across very large numbers of documents.   
It's very good for its intended usage pattern, but that pattern is not  
the same as the usage of relational databases.  The technologies are  
complementary.


I've done a bunch more performance tests. I don't understand some of  
the differences.
I hadn't realized that coredata in the data model has a flag to  
index a field. When I did that for Coredata, it dramatically sped it  
up. Although adding an index to my sqlite test slowed it down.


Your test results are very odd, in that they are still 50x to 100x  
slower than I would expect.  These tests have not yet applied the  
derived property optimization I suggested, correct ?


As literally noted here, none of those queries are eligible for an  
index, so I assume your actual code is doing something slightly  
different, or the timing difference are due to configuration issues.
Hot I/O and cold I/O will be very different.  For example:


search, without an index (cold I/O)
add an index (page everything into the UBC cache)
search, with an index, but a query that doesn't use the index (hot I/O)

The difference between hot and cold I/O for query performance will be  
huge.  As much as 100x.  You can use /usr/bin/purge to force  
everything to be cold I/O.  Not necessary representative of real world  
performance, as the whole disk cache will be flushed, including  
material relevant to the system that would normally exist when you run  
your app.


Coredata, without an index, predicate name like foo, 20 databases  
400k records each. 2m17s.
Coredata with an index, predicate name like foo, 20 databases 1mil  
records each, 25 seconds.
SQLite no index, sql where name like foo%bar, 20 databases 1mil  
records each 11 seconds.
SQLite index, sql where name like foo%bar, 20 databases 1 mil  
records each 30 seconds.


Why the 20 database files ?  These queries will be faster with a  
single database file and its unified index.


In any event, the derived property optimization should make all the  
prefix/equality queries subsecond.  On my laptop, for 20 million  
records, that should be in the 500ms ballpark (hot I/O)


As you said, with an index, and testing for equality, both coredata  
and sqlite queries responded in 1 sec. SQLite without an index was  
9 seconds for same query.


That sounds about right.  It'll be faster if you use a single database  
with 20 million rows and a unified index table.


I can only presume SQLite slowed down with an index because the  
database file was physically much larger and took longer to read  
from disk.


I suspect its a flaw in the testing methodology, actually.  Do you run  
the queries multiple times, throw out the best  worst and average the  
rest ?  Are you running other apps at the same time you do performance  
tests ?


It is possible for the presence of an index to negatively impact a non- 
indexed query, but that would be a few %, not 3x slower  An indexed  
query would read many fewer pages from disk than a non-indexed query,  
regardless of the file size.  O(lg(N)) instead of O(N) and at 20  
million that's a big difference.  There are other possible issues in  
play, but you said the result set is small, so they seem unlikely.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev

Re: CoreData async fetch request

2009-10-07 Thread Ben Trumbull


On Oct 6, 2009, at 8:29 PM, David Melgar wrote:


Hello,
Thanks for the response. Seems that its straying somewhat from my  
original question.


Sure, your original question is that you have a serious performance  
issue, and you'd like to hide it from the user by adding threads.  I'm  
proposing fixing the performance issue instead, and not bothering with  
the additional complexity of threads, at least until you have 100  
million rows or so.


For the 1.4 million row db I have handy, the indexed == query runs  
over 100x faster than the LIKE query.   == returns 4 rows out of 1.4M  
in 4ms and LIKE returns 4 rows in 450ms.  So, on my 2007 Mac Pro, your  
10 million row database would run in its query in less than 100ms.   
Too fast for meaningful human perception.  Do we really need to add  
threads for this ?  The code to incrementally and asynchronously  
display the results will probably take longer than Just Do It.


Searching based on prefix matching is fine.  The predicate I'm using  
really is of the form SELF like foo, no wildcard, so it doesn't  
seem that it should be that expensive.


Locale aware Unicode regex is very expensive.  Unicode is the worst  
possible text encoding system ever conceived, except for the others.   
Core Data insulates you from this so that your searches behave like OS  
X customers around the world expect.  You're welcome to learn all  
about Unicode and ICU, and work with it directly in SQLite if you  
prefer.  It'll take a lot of code to make searching and sorting work  
for every locale.


You say its possible to structure this to use a binary index. How? I  
don't see any mention of indices in the Coredata documentation.


See the Derived Property example on the ADC web site that I've  
referenced repeatedly.  However, if you're not using any wildcards,  
and your search is case sensitive, then you might as well just use ==  
and be done.  Be sure to add an index to the attribute in your model.


If I use SQLite directory, presumably I can set indices on the  
fields I want and more closely manage the data model.


You would presume incorrectly.  Generally, LIKE queries are not  
eligible for indices.  There are some special circumstances where they  
can be, but that won't work with Unicode.  You're welcome to verify  
that for yourself.


I don't see how setBatchFetchSize helps. Doesn't it just limit the  
number of results returned?


No.  It's more closely an in memory cursor.  It will require the  
entire WHERE clause execute, which unfortunately is your primary  
problem, but it will not restart the query as you stream through the  
results.


I have no idea how quickly the results will come in. Setting a size  
1 is therefore indeterminate and may take the full 3 minutes. If I  
set it to one, and I want to try and get the second row as well, it  
appears that it starts the query all over again, worst case  
resulting in 6 minutes before the 2nd result shows up. Doesn't seem  
that it scales reasonably if I want to display the first 10-20  
entries.


No, -setFetchBatchSize does not restart the query.  That's what using  
fetchOffset does (in the database, not Core Data, which is why we  
wrote fetchBatchSize ourselves)


My issue with Coredata is that it NSFetchRequest always returns ALL  
the results of the particular query at one time. If I use SQLite  
directly... assuming it supports cursors, I can get each result one  
at a time as they show up, display it to the user without slowing  
down the query as it continues to find other results.


If you try using -com.apple.CoreData.SQLDebug you will see both the  
SQL we pass to SQLite, and some performance annotations like:


2009-10-07 17:52:15.107 Address Book[13949:5403] CoreData: annotation:  
sql connection fetch time: 0.0013s
2009-10-07 17:52:15.108 Address Book[13949:5403] CoreData: annotation:  
total fetch execution time: 0.0020s for 14 rows.


The first line is how much time was spent in SQLite.  If you run this  
with your text queries, you'll see most of your time spent there.   
Switching to use SQLite directly is not going to change that.  Again,  
you should verify that for yourself.


NSFetchRequest could support a delegate to invoke some method when  
for each item that has been found, rather than blocking until all  
the results are received.
It also could have been implemented as a virtual queue, an object  
which could be read from while being written to in another thread.


That would make an excellent feature request.  Please file it with 
bugreport.apple.com

But if you take my advice and make the query run in 1.8s instead of  
180s, how important is this to you ?


- Ben


On Oct 6, 2009, at 4:08 AM, Ben Trumbull wrote:



On Oct 5, 2009, at 7:00 PM, enki1...@gmail.com wrote:

I am doing a simple query search for a text string pattern (ie  
'SELF like foo') on ~10 million small records stored persistently  
using sqlite. This is a performance test to make sure I get

Re: CoreData async fetch request

2009-10-06 Thread Ben Trumbull


On Oct 5, 2009, at 7:00 PM, enki1...@gmail.com wrote:

I am doing a simple query search for a text string pattern (ie 'SELF  
like foo') on ~10 million small records stored persistently using  
sqlite. This is a performance test to make sure I get reasonable  
performance from my database engine before I commit too much code to  
it.


Well, @self like 'foo' is a different problem than @self like  
'*foo*'.  LIKE queries require Unicode compliant regex and are  
intrinsically expensive.  If you do not have a wildcard, you are  
better off use an == query.  The DerivedProperty ADC example shows how  
to transform the text to make it much faster to search.


If you do need to use a wildcard, you'll really want to stick with 1,  
either prefix matching or suffix matching.  The DerivedProperty  
example shows prefix matching.  It's possible to structure this to use  
a binary index, and make the query extremely fast even for millions of  
records.  There is a huge difference in computational complexity.   
Prefix matching can use an index, and therefore can run O(lg(N)).


*foo* (contains) searches are slow, and cannot use an index.  You  
really want to avoid these.  Even Spotlight does not do arbitrary  
substring matching.  Compare help with elp in your Spotlight  
results.  If you want word matching, you can use Spotlight or  
SearchKit to build a supplemental FTS index.


The query is taking over 3 minutes with a small result set. This is  
on a new 13 macbook pro w 4gb memory.


... a full table scan executing a regex on each of 10 million rows on  
a 5400 rpm drive ?  Well, for doing all that, 3 minutes sounds pretty  
fast.


Just as a reference point, if you grab the objectIDs from the result  
set, and execute an IN query selecting those objects, how long does it  
take ?  50ms ?  100ms ?


The query is taking too long for a user to sit and wait for it. Is  
there a way to speed it up? Can indexing be applied to it?


I had thought if I could display results as they are found that  
might be reasonable. In my tests, if I use setFetchBatchSize and  
setOffset to restart it, then it ends up repeating the query taking  
that many times longer to get a result. Not reasonable. It does not  
seem to start the query where it left off, as a database cursor  
would do.


You can use -com.apple.CoreData.SQLDebug 1 to see the SQL we pass to  
the database.  This also has nothing to do with Core Data.  This is  
how offset queries behave.  I realize it's not what you expected,  
which is why I recommended using -setFetchBatchSize: instead.


My impression is that my usage scenario is not an appropriate use of  
core data.


Core Data is just passing the query off to the database.  I'm not sure  
why you think going to the database directly will do anything for the  
179.9 / 180.0 seconds it takes to evaluate the query in the database.



I was planning to try SQLite directly. Would it be more appropriate?


You can try it directly, but it won't have any meaningful effect on  
your performance results except that SQLite's built in LIKE operator  
doesn't support Unicode.  It'll be a tiny bit faster for that, but  
still the same order of magnitude.  And then, either you'll have to  
integrate ICU support as Core Data does, and it'll be exactly the  
same, or be stuck with ASCII.


Regardless, you'll need to make your searches eligible for an index.   
The DerivedProperty example shows how to do that.


- Ben



Thanks

On Oct 5, 2009 7:14pm, Ben Trumbull trumb...@apple.com wrote:
 Is there a way to do an asynchronous fetch request against Core data
 returning partial results?

 That depends on whether it's the query part that's expensive (e.g.  
WHERE clause with complex text searching and table scans) or simply  
the quantity of the row data that's your problem.  For the latter,  
you can just use -setFetchBatchSize: and be done.



 You can use a separate MOC on a background thread to perform  
asynchronous work.  You can then pass over results to the main  
thread to display to the user.  However, unless your search terms  
are very expensive, it's usually easier and faster to use - 
setFetchBatchSize: synchronously.  For well indexed queries, it can  
handle a million or two rows per second.  Not sure why you'd subject  
your users to that kind of experience.  It's common to use fetch  
limits, count requests, and only show the top N results.  What's  
your user going to do with a hundred thousand results anyway ?



 If you need to attack the computational expense of your query  
terms, that's more complicated.  Obviously it would be best to  
optimize the queries and ensure they are using an index.  But if  
that's not enough, you can execute the queries in a background MOC,  
fetching objectIDs + row data (put in the the row cache) and then  
have the other MOC materialize the objects by ID from the row  
cache.  There's a BackgroundFetching example in /Developer/Examples/ 
CoreData.  It shows how to do

Re: Address Book-style editing

2009-10-05 Thread Ben Lachman

Brad:

My app, SousChef, does this.  The way adress book and SousChef do it  
is to use a customized textview.  You add custom attributes to mark  
the different fields (textview's NSTextStorage is a subclass of  
NSAttributedString).  Then you control selection based on these  
attributes when in edit mode.  When a field is selected, you just draw  
a editing box + drop shadow around the full range of the field.  To  
get the plus/minus buttons (which I'm actually kind of thinking about  
removing from SousChef), you can stick them in a customized rulerview  
as markers and show/hide the ruler based on editing mode.


Hope this helps,
-Ben

On Oct 1, 2009, at 1:21 PM, Brad Gibbs wrote:


Hi,

I'm trying to re-create Address Book's editing style - if a user  
pushes a button labeled Edit, subsequent clicks on a label bring up  
what looks like a separate view for the new information.  Clicking  
return after editing commits the edit and moves on to the next field.


I'd also like to be able to have the plus and minus signs next to  
phone numbers, email fields, etc.


I don't see a stock Cocoa / AppKit way to do this.  Does anyone know  
of a public framework that mimics this behavior?  Short of that, any  
ideas on how to re-create the editing field that pops up?



Thanks.

Brad
___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/blachman%40mac.com

This email sent to blach...@mac.com


--
Ben Lachman
Acacia Tree Software

http://acaciatreesoftware.com

email: blach...@mac.com
twitter: @benlachman
mobile: 740.590.0009





--
Ben Lachman
Acacia Tree Software

http://acaciatreesoftware.com

email: blach...@mac.com
twitter: @benlachman
mobile: 740.590.0009



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: CoreData async fetch request

2009-10-05 Thread Ben Trumbull

Is there a way to do an asynchronous fetch request against Core data
returning partial results?


That depends on whether it's the query part that's expensive (e.g.  
WHERE clause with complex text searching and table scans) or simply  
the quantity of the row data that's your problem.  For the latter, you  
can just use -setFetchBatchSize: and be done.


You can use a separate MOC on a background thread to perform  
asynchronous work.  You can then pass over results to the main thread  
to display to the user.  However, unless your search terms are very  
expensive, it's usually easier and faster to use -setFetchBatchSize:  
synchronously.  For well indexed queries, it can handle a million or  
two rows per second.  Not sure why you'd subject your users to that  
kind of experience.  It's common to use fetch limits, count requests,  
and only show the top N results.  What's your user going to do with a  
hundred thousand results anyway ?


If you need to attack the computational expense of your query terms,  
that's more complicated.  Obviously it would be best to optimize the  
queries and ensure they are using an index.  But if that's not enough,  
you can execute the queries in a background MOC, fetching objectIDs +  
row data (put in the the row cache) and then have the other MOC  
materialize the objects by ID from the row cache.  There's a  
BackgroundFetching example in /Developer/Examples/CoreData.  It shows  
how to do this.  Returning partial results incrementally would require  
some creativity on your part to subdivide the query into several.   
Since most expensive queries are text searches, it's usually possible  
to subdivide the result set naturally.  Like the first letter of  
'title'.  Similar to the thumb bar index on the side of the Contacts  
app on the iPhone.


There's also a DerivedProperty example on ADC for optimizing text  
queries.



Obviously, Apple's own Spotlight could not use something like
Coredata, since it heavily relies on returning asynchronous partial
results.


Which is neither here nor there.  Most Cocoa applications wouldn't  
want Spotlight to be the sole persistence back end of their data.  The  
latency of putting all your data in a full text index instead of a  
relational database or keyed archive would be pretty absurd.  Now, if  
you're writing an app that's primarily structured around full text  
searching, you might instead prefer to focus on putting your data in  
Spotlight via small files, and using the Spotlight APIs.  But it's not  
suitable for apps interested in an OOP view of their data.



Frankly, this is my second application I've attempted to use Coredata
to find it come up surprisingly short. The first time the issue was
core data not being thread safe.


Core Data can be used efficiently with multiple threads.  It might  
help to think of each MOC as a separate writeable view.  If you'd like  
to know more, you can search the archives for my posts.



What is the target market for Core Data? Why sort of application is
ideal for its use? What size data store? Right now it escapes me.


Cocoa and Cocoa Touch applications, particularly done in an MVC style  
with an OO perspective on their data.  Some people also use it as a  
persistent cache for data stored in another canonical format, such as  
XML files.  On the Mac side, we've had customers with 3+ million rows  
(multi GB) databases, and on the embedded side, roughly 400,000 rows  
(100s MB).  However, it does take some care and feeding to handle data  
sets like that, and most developers find it straight forward up to  
about 10% those numbers.


It sounds like you're having performance issues.  What kinds of  
queries are you trying to accomplish ?  How much data are you working  
with ?  How have you modeled your primary entities?


You can fetch back just NSManagedObjectIDs, and - 
setIncludesPropertyValues: to NO to effectively create your own  
cursors if you prefer.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: whether to use core data...

2009-10-05 Thread Ben Trumbull

But the Core Data documentation starts like this:

...
Core Data is not an entry-level technology.
...
You should not simply try to read [The Core Data Programming Guide]
straight through to understand Core Data.
...
Do not attempt the NSPersistentDocument Core Data Tutorial unless or
until you also understand Cocoa bindings.
...
Although Cocoa bindings and Core Data are independent and address
different issues, both provide abstraction layers that˜while
individually they are reasonably straightforward to grasp˜can be
challenging to master simultaneously.


Bloody hell!

WARNING! Do not even ATTEMPT the NSPersistentDocument Core Data
Tutorial! Your very MIND is in MORTAL DANDER!


Ironically, the Low level Persistent Store tutorial was a lot easier  
for people new to Cocoa.  I believe it's been replaced by http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CoreDataUtilityTutorial/Articles/00_introduction.html 



The warning is a touch harsh.  Still, it's there because the Core Data  
abstractions are built on top of the other foundational Cocoa  
elements.  If you don't get KeyValueCoding, you're going to be lost.   
It wouldn't be doing you any favors to suggest otherwise.  Ditto for  
Cocoa collection classes, KVO, and NSNotificationCenter.


The NSPersistentDocument tutorial is more difficult because it's at  
the intersection of several different technologies.  NSDocument from  
AppKit, Cocoa Bindings, and Core Data.  So that's learning 3 separate  
things at once, and it's rarely clear to people new to Cocoa where  
those technologies intersect, and where they are distinct.  It'd be  
like learning how to whistle, juggle, and snap all at  once.  Could  
you ?  Sure.  But experience has demonstrated it's easier and  
significantly less frustrating to learn them separately.


Or put another way, some of the tutorials are intended for advanced  
Cocoa developers new to Core Data, not developers new to Cocoa.  Try  
the Core Data Utility Tutorial.  It's a CLI, so you don't have to get  
wrapped up in NSViews or Cocoa Bindings as you experiment with Core  
Data.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Strange Core Data save behaviour (required relationship nil... when it is set the line before saving)

2009-09-30 Thread Ben Trumbull


On Sep 30, 2009, at 12:56 AM, Luke Evans wrote:

Well, I'm more than happy to file a bug, as it has been tricky to  
figure out (and I would probably still be at it without your  
interjection).
There are several ways to frame the problem of course: it could be a  
documentation bug... things aren't as simple as might first appear  
in the docs/guide, or maybe something can be done to have deleted  
object behave in a 'friendlier' manner w.r.t. their defunct  
relationships.  I suppose I can just find a general form of words  
and let you good folks figure out what it really means in practice :-)


Probably some of both.

I still think I might have something more to figure out here too.   
At the end of my testing, as an experiment I had a main thread timer  
fire periodically to perform a save on the main thread's MOC  
(without performing any changes on the main thread's MOC at all).   
This induced the same problem, and I'm still curious as to how the  
main thread's copy of the graph might have the nil in the  
relationship under these conditions.  AFAICS there shouldn't have  
been any chance for either MOC to be in this condition at any time.   
I assume the merge operation from the other thread is 'atomic'  
somehow and activity on another thread (like a save) should not be  
able to catch that MOC in some kind of in-between state?


merge ?  I'm not sure I have a full grasp on your work flow here.  If  
you call mergeChangesFromContextDidSaveNotification, then that can  
obviously make changes to the object graph.


There are two other issues in play.  First, if you've set a merge  
policy, then the MOC may pull in changes necessary to make the save  
correct (e.g. implement and correct an optimistic locking failure).   
Second, firing a timer on the main thread is totally non-deterministic  
with respect to anything else on the main thread.  The application  
event loop is rather amorphously defined, so timers can fire either  
inside or outside the main thread's current event's undo grouping.   
Timers are intrinsically very unpredictable.


Aside from this 'stress' test though, I haven't (yet) got it to fall  
over - essentially under the conditions where only one thread  
(albeit one of several threads on any occasion) is making changes  
and saving at a time.



I'm not sure I understand this last comment.  Do you have threads  
sharing a MOC ?  Because threads with their own MOCs can make their  
own changes and own saves simultaneously.


- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Strange Core Data save behaviour (required relationship nil... when it is set the line before saving)

2009-09-30 Thread Ben Trumbull



I don't think anyone has cared enough to file a bug on this.


I don't get it. There's an open manhole in the street with the manhole
cover lying right next to it, and the problem is that no one cared
enough to call the Department of Works to complain?



This has come up 3 or 4 times in about 6 years.  So, is it an open  
manhole in the middle of the street, or is it that the unpaved road  
behind your house that nobody uses is missing a street sign ?


A quick glance suggests this should be pretty easy to fix, but that  
the obvious fix will be slower.  Should everyone's deletes get slower  
just to spare Luke ?  Maybe.  Hard to say without quantifying it.  So,  
now some performance tests need to get written, and the results  
measured.  Also, there's no bug report, and no developer provided test  
case to verify the fix.  So that needs to get written too.


Should we spend our time on this or, judging by complaints, something  
more important ?


cocoa-dev is not a bug reporting forum.

- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Strange Core Data save behaviour (required relationship nil... when it is set the line before saving)

2009-09-29 Thread Ben Trumbull

Now, I have some code that changes the value of the 'B enumeration
value' that A is using.  This does the following:
1. Create a new instance of the B subentity that represents the value
we want (in the same MOC as A)
2. Delete the old B object that A was pointing to, i.e. [moc
deleteObject:B];
3. Set A's to-one relationship to point to the new B object (and for
good measure, set B's inverse relationship - though this should be
done automagically).
4. Save the moc

4. is where badness happens (failed to save).  The error tells me that
A's relationship property to B is nil... but just before I do the save
I log the value of the object referenced by this relationship and it's
the new 'B' object!
I have no idea what I've done to upset Core Data such that it claims a
relationship is nil when I save, but the line before the [moc
save:err], the relationship shows as referencing a perfectly good
object.


So you delete B, which has an inverse relationship to A.  Then you set  
a new B on A.  Then you save, and delete propagation cleans up the  
graph, nullifying the old B's inverse relationship ?


What happens if you add a call to -processPendingChanges in between #2  
and #3 ?


- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Strange Core Data save behaviour (required relationship nil... when it is set the line before saving)

2009-09-29 Thread Ben Trumbull


On Sep 29, 2009, at 8:22 PM, Luke Evans wrote:


Hello Ben.

What happens if you add a call to -processPendingChanges in between  
#2 and #3 ?


... well then everything works wonderfully (oh joy!!) :-)

OK.  I need to get a proper mental picture of why this is needed in  
this case.
I guess I was vaguely aware of this method from previous passes  
though the Core Data docs, but...


- The method documentation itself doesn't _really_ suggest it may be  
essential in some cases.   Rather, the talk is about getting the  
undo manager into step, and even then the statement is made that  
this is done by default at the end of the run loop.
- deleteObject docs, or indeed the guide section on deleting  
(Creating and Deleting Managed Objects) makes no mention of a need  
to call this method
- I had tried manually setting the old deleted objects 'back  
relationship' to nil, before deleting it, and before setting A's  
relationship to the new B.  This hadn't worked, but was my attempt  
to keep the relationships consistent - at least in in the MOC that  
induced the change.


It's tempting to just think that you should _always_ do a - 
processPendingChanges before a -save:, but I'd prefer to understand  
what's really happening here.


It's not before the save.  It's in between the deletion and the re- 
assignment of the relationship of the surviving object to a new  
object.  The problem is reassigning the relationship before delete  
propagation runs.  Delete propagation, as well as the change  
notifications and several other aspects of object graph change  
tracking are coalesced and run later.   Calling processPendingChanges  
is one of those later times.  The application event loop also calls  
it, which is the default timing.  Executing a fetch, or a save will  
also call it.


Manually setting the deleted object's relationship instead of calling  
processPendingChanges between steps #2  #3 should also work.


I don't think anyone has cared enough to file a bug on this.

- Ben



If you have insights on the above, then that would be great.   
Regardless, you've just improved my humour by several degrees ;-)


-- Luke


On 2009-09-29, at 3:59 PM, Ben Trumbull wrote:


Now, I have some code that changes the value of the 'B enumeration
value' that A is using.  This does the following:
1. Create a new instance of the B subentity that represents the  
value

we want (in the same MOC as A)
2. Delete the old B object that A was pointing to, i.e. [moc
deleteObject:B];
3. Set A's to-one relationship to point to the new B object (and for
good measure, set B's inverse relationship - though this should be
done automagically).
4. Save the moc

4. is where badness happens (failed to save).  The error tells me  
that
A's relationship property to B is nil... but just before I do the  
save
I log the value of the object referenced by this relationship and  
it's

the new 'B' object!
I have no idea what I've done to upset Core Data such that it  
claims a

relationship is nil when I save, but the line before the [moc
save:err], the relationship shows as referencing a perfectly good
object.


So you delete B, which has an inverse relationship to A.  Then you  
set a new B on A.  Then you save, and delete propagation cleans up  
the graph, nullifying the old B's inverse relationship ?


What happens if you add a call to -processPendingChanges in between  
#2 and #3 ?


- Ben


___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Snow Leopard, core data, read only and multiple threads

2009-09-27 Thread Ben Trumbull
I've got an app that worked on Leopard. I ported it to Snow Leopard  
SDK 10.6, and now it works on Snow Leopard, but it doesn't work  
correctly on Leopard anymore. I haven't changed anything that ought  
to affect this.


What doesn't work ?

It's an app with a foreground gui that writes an XML coredata store.  
A background thread reads the repository and takes action. Both  
threads have the full core data stack with their own coordinators.  
As soon as I activate the background thread, the XML store gets set  
to zero bytes.


The XML store is an atomic store.  Everything is loaded at once, and  
everything is written out for each save.  Very NSDocument like.  Like  
TextEdit.  Two people open up Text Edit, pointed to the same path  
mounted over a shared volume.  What happens ?


You almost certainly want to use the SQLite store, or have the stacks  
work with different XML files.


When I encountered the problem I read the doco and I added the  
NSReadOnlyPersistentStoreOption when calling  
addPersistentStoreWithType in the background thread, but that hasn't  
helped. It wasn't necessary before.


NSReadOnlyPersistentStoreOption doesn't have anything to do with multi- 
threading.


You sure you're not saving a MOC ?

- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Re: [__NSFastEnumerationEnumerator nextObject] unexpectedly not very fast!

2009-09-25 Thread Ben Trumbull

In summary, the existence of fast enumeration does nothing for
existing enumeration technologies and if you have to support
10.4 (as I do) you simply can't use it unless you fork your code.

My solution, in the few cases where performance is paramount,
has been to essentially roll my own fast enumeration. For very
large arrays (thousands of objects) I'll get blocks of objects
in batching using [NSArray getObjects:range:], process those in
a tight C loop, and then get another batch.


The for (in) construct is by far the most optimized general purpose  
way to work with any of the collections in Cocoa on 10.5, 10.6, and  
iPhone OS.  It's also polymorphic, so custom collection subclasses can  
fine tune the behavior.


If you have to hand roll your own, either for 10.4, or some  
specialized case, your best bet is to use -getObjects: into a local  
buffer.  gcc supports variable length arrays, and that's the fastest  
way to marshall these batches temporarily.  You'll want to be very  
careful to do length checks to not overrun your stack, and limit the  
size.  If you have somewhere between 256  512 objects, give or take,  
you'll have to malloc a temporary id*  Overflowing the stack is not  
pretty.


- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Core Data: relationship 'too large' when saving

2009-09-24 Thread Ben Trumbull

I am encountering an error that I have not seen before.

While saving in a NSManagedObjectContext I am encountering an error
that reports a to-many relationship as 'too large'.
This relationship has ~10,000 members but each member is relatively
simple consisting of a few short strings and numbers.
I have no problems operating on this relation; the error only occurs
while saving.
Many GB of disk space are available. Error occurs independent of store
type, SQLite, binary, or xml.
Smaller (different) relations of ~1000 members are correctly saved.

1) Is this really a size problem?


No.  I suppose it's possible there's a 16 bit overflow bug somewhere,  
but there shouldn't be (obviously), and I can't imagine any issue with  
10,000.  It is possible for you to set the maximum size of a to-many  
relationship in your model.  Did you check the property validation  
rules for this relationship ?



2) can someone point me to relevant documentation?


You sure it's not NSValidationNumberTooLargeError for one of the  
numbers being outside the range you specified acceptable in the model ?


- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Core Data memory not freed after reset

2009-09-22 Thread Ben Trumbull


On Sep 22, 2009, at 8:54 AM, Sean McBride wrote:


On 9/21/09 4:21 PM, Ben Trumbull said:


If you're using an NSArrayController in Entity mode, you can turn on
Use Lazy Fetching.  You'll want to disable auto-rearrange content.


Ben,

May I ask, why turn off 'auto-rearrange content'?  Is it not  
compatible

with 'use lazy fetching'?  Or does
'auto-rearrange content' on its own degrade performance somehow?



auto-rearrange content is very expensive.  Preserve selection can also  
be expensive, although not nearly as bad.  But if we're talking about  
a million object table view (which is a little odd, btw, most UIs have  
... and more instead) then extraneous layout options will add up fast.


I have a vague and hazy memory that auto-rearrange content is not  
compatible with use lazy fetching.  If you run into trouble, file a  
bug, and disable auto-rearrange content as a workaround.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Core Data memory not freed after reset

2009-09-21 Thread Ben Trumbull

in my SQLite backed Core Data app, a search action fetches from a
large number of objects (1.000.000) only to show them in a table.
When the user exits search mode (search string empty), I'd like to
free the managed objects to restore the app's normal memory footprint.
I do that by resetting the managed context, but it doesn't seem to
work, physical memory stays where it was when the fetch was completed.
Strangely, in ObjectAlloc instrument I can see the fetched objects
being deallocated, but the physical memory still peaks.


If ObjectAlloc shows the fetched objects being deallocated, but top  
shows a large RSIZE, and the heap command shows a very large heap  
thats most unused, then you're doing everything you can on the  
deallocation side.  There is a difference between heap size, and VM  
allocated address space.  This issue is caught at the boundary, where  
the malloc system won't aggressively deallocate address space after  
the memory using it has been deallocated.  It doesn't, because as a  
general rule that's a net loss.  So your only choice is to either (a)  
not worry about it or (b) reduce peak memory.  (b) reducing the heap  
high watermark is a separate problem than simply freeing all the  
memory you allocate.  Reducing peak memory will have many other  
performance benefits besides making your RSIZE look pretty.


If you're using an NSArrayController in Entity mode, you can turn on  
Use Lazy Fetching.  You'll want to disable auto-rearrange content.   
This works on 10.5.  On 10.6 and iPhoneOS, you have more options,  
including using Batched Fetching on the fetch request with - 
setFetchBatchSize.  This will make a vast reduction in peak memory  
when working with such a large result set.   Working with 1 million  
objects like this will take ~16MB of RAM.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Core Data memory not freed after reset

2009-09-21 Thread Ben Trumbull

Core Data has (or, I should say, had, since I haven't investigated the
behavior in Snow Leopard) its own internal in-memory cache of object
and attribute data, which means that, up to a point, data from a
persistent store is in memory twice. AFAICT there's no way of
unloading or controlling this cache, which has a maximum size that
Core Data chooses.

So you can get back the memory occupied by the objects themselves (and
their attribute value objects), but your memory footprint could stick
at a couple of hundred MB. You could just ignore the issue (the
footprint won't grow beyond certain point, so it's sort of harmless),
or try some of the fetch performance optimization techniques described
in the Core Data documentation to see if you can keep unwanted
information out of the cache from the beginning.


The caching is happening at the NSPersistentStoreCoordinator level,  
and is shared copy-on-write with the managed objects themselves (e.g.  
faulting the same object in multiple MOCs will reuse the same string  
data).  The raw column data is not duplicated in memory.  The cache  
entries are deallocated after the managed object representing that row  
is deallocated, and at certain other times involving faulting.  Simply  
releasing the last managed object representing that row is enough.   
You may need to call -processPendingChanges to purge anything that as  
accumulated as ready to be disposed to encourage this to happen sooner  
if you find it's taking too long.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Core Data threading fun

2009-09-21 Thread Ben Trumbull

I have a server app that responds to network requests, making use of a
Core Data database to serve responses.
Some requests update the database.  I have chosen to allow requests to
arrive on multiple threads, and intend for these threads to use Core
Data directly.

In keeping with Core Data's doc related to threading, I have one
Managed Object Context per thread, and these all share a common
Persistent Store Coordinator that is managing a SQLite data file.
It's my understanding that this scenario is an acceptable
configuration, indeed it appears in the Core Data notes on threading
as the 'preferred option' (q.v. 
http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CoreData/Articles/cdMultiThreading.html
).

OK, here comes the problem (!)...
One type of request can change the name of an object.  The handler for
this request (using its thread's own MOC):
1. Fetches the required object by persistent ID (i.e. stringified
NSManagedObjectID).


Why stringify it ?  NSManagedObjectIDs are immutable and you can just  
pass them between threads.



2. Changes the value of the 'name' property on the fetched object
3. Commits the change by calling 'save' on the MOC

Unfortunately, while this works some of the time, I have a situation
where a subsequent other request (possibly on another thread) sees the
old name of this object.  This request gets 'all' the entities of this
type and sends properties (such as name) back.


You can merge the changes into that context explicitly, or refetch the  
objects.



Should I have a PSC per thread too?  If so, will they behave correctly
talking to the same SQLite data file?
With a shared PSC, should I lock this whenever a write is being
performed (at least)?


Per-thread PSCs doesn't sound like what you want.  You probably want  
the simpler shared PSC configuration for now.  When you share a PSC  
between threads, the key point is to lock it whenever you message that  
PSC directly yourself.  Typically, that's adding and removing  
persistent stores.  It's easier to do that at init time, and leave the  
configuration stack after you start spawning threads.  Core Data  
assumes responsibility for locking the PSC if we ever send ObjC  
messages to it.




2. Locking the MOC
There is talk that locking the MOC, even one that is private to a
thread, will engender 'thread friendly' behaviour in the PSC:

...
Typically you lock the context or coordinator using tryLock or lock.
If you do this, the framework will ensure that what it does behind the
scenes is also thread-safe. For example, if you create one context per
thread, but all pointing to the same persistent store coordinator,
Core Data takes care of accessing the coordinator in a thread-safe way
(NSManagedObjectContext's lock and unlockmethods handle recursivity).
...

Should I lock the MOC, or just the PSC (see 1)?
Would this really fix my experience of changes not appearing on other
threads anyway?


No, if you find yourself locking MOCs, you're almost certainly doing  
something wrong.



3. Changes propagating back to other MOCs looking at the same data
I assume Core Data is smart enough to realise that an attribute value
change in a Managed Object cached in one thread's MOC, should be
reflected on (or at least invalidate old data in) another Managed
Object instance representing the same data in another MOC.  At the
very least, I think I'd expect a new fetch request that has this
object in the result set would cause data changed in the persistent
store to show up properly on the object.


We don't automate this step, although there is API to assist you.  We  
try as much as possible to never change the state of your objects out  
from underneath you (e.g. push state).  The reason for that is how  
complex things become when that local MOC has pending edits.  Do we  
overwrite it out from underneath you ?  Or not update it, but update  
other unchanged objects (seemingly randomly).  There isn't a clear  
paradigm for coordinating these kinds of push changes between the  
framework and your code.  So instead we follow something like a  
principle of least surprise mates with lesser evil.


Basically, Core Data uses the poll model.  State may change, but only  
because you did something to ask us to do that.  Like refetch the  
objects, use a staleness interval, or call -mergeChanges...


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: How to create subentity object inheriting from superentity object in core data

2009-09-17 Thread Ben Trumbull


On Sep 17, 2009, at 9:21 AM, Leon Starr wrote:

So, going back to my example, (and the part everyone disagrees  
with!) I still don't get it.  More importantly, my objc compiler  
doesn't get it!  In the model, Auto.license is properly inherited by  
the Sedan and Truck subentities.  No trouble at all with KVC  
interactions.  But if there is no @property/@dynamic for license in  
my Truck subclass, (only in the Auto subclasss) I cannot access  
thisTruck.license without getting a compiler error.  Which makes  
total sense to me since one NSManagedObject subclass (Truck) is not  
inheriting from another (Auto) in objc.  They each inherit from  
NSObject.  But I CAN do [thisTruck valueForKey:@license], which  
also makes perfect sense.


This violates the rule that a subentity must use an Objective-C class  
that is the same as its superentity, or a subclass of its  
superentity's Objective-C class.


If the Truck entity is a subentity of Auto, then it may reuse the  
AutoClass, or a TruckClass which must be a subclass of the AutoClass.


- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Core Data: strange keypath problem

2009-09-17 Thread Ben Trumbull

Here is the console output:
2009-09-17 12:44:17.659 myAppSales[11094:a0f] Application DMXRef:
janTotal starting...
2009-09-17 12:44:17.660 myAppSales[11094:a0f] Application DMXRef:
janTotal predicates set.
2009-09-17 12:44:17.662 myAppSales[11094:a0f] anotherArray count = 117
2009-09-17 12:44:17.663 myAppSales[11094:a0f] anotherArray firstObject
month = 5
2009-09-17 12:44:17.663 myAppSales[11094:a0f] keypath month not found
in entity NSSQLEntity AppSales id=2

Any ideas would be greatly appreciated.


Is 'month' marked transient on the AppSales entity  in your model ?   
You cannot ask a *persistent* store to query or sort on *transient*  
data.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Custom Fonts in UI Webview

2009-09-16 Thread Ben Lachman


On Sep 15, 2009, at 10:08 PM, Alex Curylo wrote:



On 15-Sep-09, at 6:57 PM, cocoa-dev-requ...@lists.apple.com wrote:


You can do custom fonts on the iPhone, but you cannot use system
controls to draw with them. You have to draw yourself each glyph.


Sure you can. It's just tricky.

http://www.alexcurylo.com/blog/2009/05/29/custom-fonts/


I had seen some hints at this in my searching, and this looks to be  
quite a nice implementation and should make using custom fonts fairly  
straight forward.


However, my original question was regarding web views and whether  
there was a way to include custom fonts in the application bundle and  
then access them for use in a UIWebView.


Best,
-Ben
--
Ben Lachman
Acacia Tree Software

http://acaciatreesoftware.com

email: blach...@mac.com
twitter: @benlachman
mobile: 740.590.0009



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: How to create subentity object inheriting from superentity object in core data

2009-09-16 Thread Ben Trumbull

I've got a generalization in my core data model with entities named A,
B, C let's say where A is a super class with subentities B and C.

A is not abstract, so if I create an A NSManagedObject, I need to
create and relate a single B or C subclass object. How do I make this
happen? I can create the entities, but HOW do I tell the model that
object B is a subclass of object A (or vice versa?)

Note: I did create the model programmatically and the subentities have
been set properly for entity description A.

Here's my sad attempt to move forward.  As you can see, I've created
the objects I need, but B doesn't know that A is it's superclass
object.  What to do?


Model the entity inheritance in the modeling tool is the easiest  
approach.  If you need to customize your model beyond that at runtime,  
you can make minor alterations programmatically by loading it and  
mutating it before creating your NSPersistentStoreCoordinator.  If you  
programmatically create a model, you'll need to add all the super  
entity's properties to each of the subentities.  The programmatic  
structure is much flatter than it would appear in the graphic Xcode  
tool.  There's no calling super in entity inheritance.


You'll need to set the objective-c class names for each entity.  The  
objective-c class must be either the same as the super entity's class  
or a subclass of that super entity's objective-c class.  You cannot  
create a random mapping of Objective-C classes to entity inheritance.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: How to create subentity object inheriting from superentity object in core data

2009-09-16 Thread Ben Trumbull

Okay, my understanding, then, is that the inheritance is just in the
model - makes sense.  If you subclass NSManagedObjects for the parent
and child entities, you need to explicitly declare and synthesize
(dynamically) all common properties you want to access at lower levels
of the hierarchy (at least).


entity inheritance is just in the model.  class inheritance still  
applies normally.



Just to be clear, in the model I've got Entities: Auto, Sedan, Truck
and the parent (Auto) has a common property license.  Now when I get a
pointer to a Sedan or Truck I want the ability to access via
thisTruck.license or thisSedan.license.  In fact, if I end up with a
pointer (Auto *) thisAuto, I want thisAuto.license as well.

To get this to work, without KVC,  I need to declare @property/
@dynamic for license in Auto, Sedan and Truck.  (Can't just put it in
Auto and expect Sedan.license to work).  No big deal unless I have a
bunch of common properties in the parent entity.


No, Objective-C properties are inherited by subclasses.  If you use  
the modeling tools, your model will be created correctly, and your  
custom NSManagedObject subclasses will have the correct @interface  
definitions.  Even if you need to do all this programmatically, I'd  
recommend to play with the modeling tools more to see what things are  
supposed to look like.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Custom Fonts in UI Webview

2009-09-15 Thread Ben Lachman


On Sep 14, 2009, at 6:08 PM, Jens Alfke wrote:


On Sep 14, 2009, at 2:43 PM, Ben Lachman wrote:

I was looking at the NYTimes iPhone app today and noticing that it  
looks like they're using a UIWebView with a custom font (not sure  
what font though, anyone know?).  I did some digging on how to do  
this and couldn't come up with anything except one bit about @font- 
face being deprecated on MobileSafari.  I saw a lot of references  
to using Cufón (or similar), however that doesn't allow for copying  
or selection and the NYTimes app does.  anyone know of a way to use  
a real custom font face in a UIWebView?


Embed the font file in your app. IIRC there is a special Info.plist  
key that points to a subdirectory containing font files, which will  
automatically be enabled. See the docs on Info.plist keys.


Then you don't need to use @font-face, you can just reference the  
font name in your stylesheet.




After some looking, I think you're talking about  
ATSApplicationFontsPath.  Unfortunately although it shows up in the  
iPhone docs, it state that it only works on Mac OS X.  I'm working on  
iPhone so this really doesn't help much.


However, I also found after checking the NYTimes app again that  
they're actually using Georgia for their font face, not anything custom.


-Ben
--
Ben Lachman
Acacia Tree Software

http://acaciatreesoftware.com

email: blach...@mac.com
twitter: @benlachman
mobile: 740.590.0009



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Custom Fonts in UI Webview

2009-09-14 Thread Ben Lachman

Hey all.

I was looking at the NYTimes iPhone app today and noticing that it  
looks like they're using a UIWebView with a custom font (not sure what  
font though, anyone know?).  I did some digging on how to do this and  
couldn't come up with anything except one bit about @font-face being  
deprecated on MobileSafari.  I saw a lot of references to using Cufón  
(or similar), however that doesn't allow for copying or selection and  
the NYTimes app does.  anyone know of a way to use a real custom font  
face in a UIWebView?


Thanks,
-Ben
--
Ben Lachman
Acacia Tree Software

http://acaciatreesoftware.com

email: blach...@mac.com
twitter: @benlachman
mobile: 740.590.0009



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: CoreData multiple contexts and threads

2009-09-13 Thread Ben Trumbull

Hello, I have a stream of data (some messages) from a socket and I
need to save it in a CoreData db. I would to optimize this thing by
using more than a managedobjectcontext for each N messages arrived.
The problem is that I need to link these message between
(parent/childs). How can I check if a message exist in a context
without merge it with the main context? Need I to mantain an array of
active contexts and comunicate with them in order to search parents
and childs? If I merge each time with the main context it's a bit
slow.


Well, you can create the messages and save them in groups in their own  
thread and MOC, and link them up with their parents later.  Or you can  
organize the background threads to own parent groupings and have those  
dedicate threads save their messages.


The problem with inserting messages and relating them to parents  
haphazardly is that the to-many relationship on Parent will need to  
merge in the results on each save anyway, and having lots of threads  
banging on the same to-many will just engender a lot of merge  
conflicts.  While the right merge policy will resolve them for you,  
that's not remotely free.  You can look up a previously saved MO with - 
objectWithID: on your MOC.


If you have  a very large number of messages, you may not wish to  
model the to-many on Parent at all.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: CoreData Bug? (SQLite vs XML)

2009-09-13 Thread Ben Trumbull

I've been trying to track down a bug and it *seems* that it might be
CoreData's fault (I highly doubt it but there's a small chance). I
have the following configuration:
- A base class, let's call it Base
- A subclass of Base, let's call it Subclass

Subclass has a to-many relationship to Base. Here's what I'm  
observing:

- On startup, the to-many relationship is not restored (only in some
reproducible cases).


Are all the objects correctly marked inserted or updated before you  
save ?  Do all the objects report the correct inverses ?


If you change relationships with setPrimitiveValue:forKey: or on MOs  
that haven't been inserted into a MOC or try to wire up relationships  
in -awakeFromFetch, then things can go awry.


Do you have multiple MOCs saving ?  The XML store is atomic, so the  
last writer wins.  The SQLite store merges changes from other saves.


Can you reproduce this in a new sample project ?

- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Core Data Manual Migration

2009-09-11 Thread Ben Trumbull

The process fails here and the log then contains the following:
An error occured while manually migrating document: Error
Domain=NSCocoaErrorDomain Code=134110 UserInfo=0xf336960 An error
occured during persistent store migration.
[6871:813] Error: {
   reason = Can't add source store;
}


There should be more in the userInfo dictionary explaining what's  
going on.  If you can reproduce it in a new test project with your  
models  mapping models, then please file a bug with the project  
source zipped up at bugreport.apple.com and we'll look at it.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Is Core Data appropriate to my task?

2009-09-10 Thread Ben Trumbull

property in the other direction? What's the predicate there,
planetOfOriginName LIKE [c] $FETCH_SOURCE.name? Now your Planet
entity has intimate knowledge of the structure of your Employee
entity; that can't be good.


If this were a join you coded yourself in SQL, the Planet table would  
effectively know which column matched in the Employee table.


Also, if you do in code or fetched properties, this hand made cross  
store relationship, you should prefer numeric keys to text strings for  
your joins.  Creating a de facto join through a LIKE query is pretty  
crazy.  That's a case insensitive, local aware, Unicode regex there.   
String operations are much more expensive than integer comparisons.   
At the very least, use == for your string compares.


Of that's true for any database.


It seems to me that Core Data really is intended to deal with lists of
root objects, i.e. the entire list of Employees in one store, rather
than one Employee per store.


One document per Employee is a bit unusual.  But it's feasible if  
that's your requirement.



The Core Data documentation mentions
attaching multiple stores to a persistent store coordinator, but I
can't make any sense of how interrelationships between the stores are
handled.


The old fashioned way.


Is Core Data really more appropriate to my dataset than an SQLite
database and a simple Employee object that fetches from that database?
If so, I'd appreciate some help in understanding how.


Are you comparing apples to apples here ?  Using multiple SQLite  
database files directly will open you up to nearly all the same  
problems you're describing for Core Data.  If you're not going to use  
multiple SQLite database files without Core Data, why would you with  
Core Data ?



(Let me take this opportunity to say that for all the warnings that
Core Data is not and never has been a database, almost every concept I
see in it makes me think O/R mapper for SQLite.)


Core Data is an O/R mapping framework, among other things.  But O/R  
frameworks are not SQL databases.  Modeling your data in any O/R  
framework as if you were writing SQL directly is inefficient and  
mistaken.


Saying that Core Data is a database is like saying your compiler is an  
assembler.  Well, the compiler suite uses an assembler, sure, and they  
both output object code in the end, but that does not mean the best  
way to use your compiler is to write in assembly.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Is Core Data appropriate to my task?

2009-09-10 Thread Ben Trumbull

I don't see this as being equivelant at all.

Extending the example, let's say the company with these Employees has
as its directors several discriminating unfair people, and thus an
Employee from any given Planet gets a salary adjustment based on that
Planet. The obvious place for this data is the Planets table, or in
Core Data's case, the Planet entity. A salaryAdj column (attribute)
is added to the Planets table (Planet entity) and filled in with the
(in)appropriate numbers.

Now suddenly the company is taken over by far more benevolent and
considerate people, whose only flaw is that they don't want to break a
system that works by removing an entire column from a database table
(a schema change is much more difficult than a data update, after
all), so they just UPDATE Planets SET salaryAdj=0.


Now you're conflating other issues.  This is why I recommend not  
treating O/R systems as perfectly equivalent to databases.  They're  
not.  On Snow Leopard  iPhone OS, you can make modest alterations to  
the Core Data schema easily.  Just keep a copy of the old model, and  
pass the 2 keys to the options dictionary when you add the store to  
the PSC to leverage light weight migration.  Core Data will infer the  
appropriate schema changes and adjust the schema in place (alter table  
style).


http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/vmLightweight.html#//apple_ref/doc/uid/TP40008426-SW1 



If you do make some unusual and radical modifications (split tables  
into multiple new tables, compose old tables into a single new table,  
etc), you can use the full mapping model migration.  While it won't  
perform as well as light weight migration, at least you'll have tools  
support in handling the schema migration.



So someone loads up an Employee whose Planet instances are in the same
store with that Employee, and the old salary adjustment is still
sitting there in the saved data. I sense unhappy Employees in this
company's future. If only the coder who wrote the payroll system had
put the Planet data in some global store where changes to it would
propogate correctly to all Employees.


If this is important, than you can use multiple persistent stores.

I suspect Erik's point, though, is many apps don't have a significant  
issue with a small amount of duplication in the individual documents.   
Disk space is usually cheap.  And being completely self contained has  
its advantages (perhaps not relevant to you, but still existent).   
global mutations is a double edged sword.  What if your documents  
are loaded in a newer version of the app, but have some implicit data  
dependency on the older global data ?  That can get messy.



Does Core Data still solve the problem? Is there some reason that
using Core Data for everything would be better than storing the global
rarely-updated data in a real database and using Core Data only for
the Employee entity, which is the only part which really talks to the
UI anyway? (Something tells me the key point is right there...) For
that matter, if Core Data is only managing one entity, what's the use
of Core Data at all? With all the data being referential between the
database and the entity, just define a simple NSObject subclass which
contains a few instance variables and implements NSCoding.



Then why not use Core Data for the database and for the entity  
implement a simple NSObject subclass with a few instances  
variables ... ?


Although, it seems a little silly to not use Core Data for the simple  
part when you'll get persistence, change tracking and Cocoa Bindings  
integration for free.  Most people find NOT maintaining backward  
compatible initWithCoder methods in perpetuity quite refreshing.  I  
know one developer seriously considering rewriting their iPhone app  
for no other reason than to use Core Data's light weight migration and  
never hand roll another database schema upgrade again.


Here's an excerpt from a post regarding when to use Core Data on the  
iPhone:


I suppose I could tell you how great an addition to Cocoa it is, or  
how much TLC its performance tuning gets.  But what I've seen our most  
sophisticated clients decide is that it saves them from writing a lot  
of code.  The model code with Core Data is usually 50% to 70% smaller  
as measured by lines of code.  Why reinvent that ?


App developers don't get paid to write database code.  Can you learn  
SQL ?  Sure.  Do your customers care ?  No.


App developers get paid for novel functionality that addresses a real  
customer need with good UI.


- Ben

Here's a more traditional reply:

- Full KVC, KVO support out of box
- Relationship maintenance (inverses, delete propagation)
- Change tracking

- Sophisticated SQL compilation
 - NSPredicate objects instead of SQL
 - NSPredicate support for correlated subqueries, basic  
functions, and other advanced SQL

 - Proper Unicode, local aware searching, sorting, regex

Re: Is Core Data appropriate to my task?

2009-09-10 Thread Ben Trumbull

Before anything else, let me say thank you for a clear, concise, and
very helpful set of answers to my questions; I was expecting rather
more of a struggle for understanding :).


my pleasure.


On Sep 10, 2009, at 5:04 PM, Ben Trumbull wrote:

The inverse
relationship from Planet to Employee, all employees from this
planet
is technically feasible, even easy, to model, but it's almost
certainly a waste of time and effort. But the Core Data  
documentation

offers a long list of very dire warnings about one-way relationships
between entities.

Yes, and for most situations those warnings are there for very good
reasons.  But if there were no reasons for such relationships, then
it wouldn't be a warning, it simply wouldn't exist.


The manual isn't at all clear about this, but if I understand
correctly, you're basically saying, Though it is almost always
technically possible to model an inverse to any relationship, there
are sometimes circumstances in which it is correct not to do so. Is
that accurate, and if so, should I file a documentation bug requesting
clarification on that and the circumstances in which it's true?


Sure.  It's a challenge to document some of this material in a way  
that steers most developers down the typically optimal path while  
still keeping advanced options open.  We have many developers with  
little or no database experience, and we want to encourage them to use  
inverses until they have a compelling reason not to.  The  
documentation was more open about no inverse relationships in 10.4,  
and we learned the hard way that was less than ideal.  The modeling  
tool now issues warnings for this due to the frequency and severity of  
bugs from developers incorrectly and over eagerly using no inverse  
relationships.



But oops, Core Data can't
model cross-store relationships, so you use a fetched property,  
which

is one-way.

You could use a fetched property, or handle this in code by storing
a URI for the destination object in a different store, and fetching
the matching objectID either lazily in in -awakeFromFetch.  We've
generally recommended using a custom accessor method for this
instead of fetched properties.


Is there any particular reason for that recommendation? The
documentation explicitly recommends fetched properties for cross-store
relationships (one instance of several is in the Core Data Programming
Guide, Relationships and Fetched Properties chapter, Fetched
Properties section, first paragraph, where it says  In general,
fetched properties are best suited to modeling cross-store
relationships...)


First, custom accessor methods and -awakeFromFetch offer a vast amount  
of flexibility, and can be easier to tune for performance.  Fetched  
properties are a fine alternative.  But I like to also reinforce the  
understanding that not all your custom behavior needs to be  
encapsulated in your Core Data schema.  You have full Objective-C  
objects and very powerful runtime support.  Use it liberally.



(Let me take this opportunity to say that for all the warnings that
Core Data is not and never has been a database, almost every
concept I
see in it makes me think O/R mapper for SQLite.)

Core Data is an O/R mapping framework, among other things.  But O/R
frameworks are not SQL databases.  Modeling your data in any O/R
framework as if you were writing SQL directly is inefficient and
mistaken.

Saying that Core Data is a database is like saying your compiler is
an assembler.  Well, the compiler suite uses an assembler, sure, and
they both output object code in the end, but that does not mean the
best way to use your compiler is to write in assembly.



Nonetheless, Core Data does manage the data stored on disk as well as
the representation of that data in memory; I don't see a tremendous
difference between that and what SQLite does, other than Core Data
providing a much effective organization of and means of access to that
data.


Core Data implements a lot of functionality on top of SQLite.  From an  
API perspective, that it uses SQLite at all is an implementation detail.


In any event, O/R systems present an OO view of your data, and have  
their own idioms closer to OOP.  They are providing an abstraction  
layer and perform transformations on both your queries and result  
sets.  Relational databases can support that, but in every O/R system,  
the ideal way of using the system is somewhat different from how one  
would write SQL directly against the database.


- Ben


___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Core Data fetch with to-many relationship

2009-09-09 Thread Ben Trumbull

When I log the test fetch results:

NSArray *testFetchResults = [managedObjectContext
fetchObjectsForEntityName:@Owner withPredicate:[NSString
stringWithFormat:@ANY books.name like 'myPrefix*']];
NSLog([[(Owner *)[testFetchResults objectAtIndex:0] books]
valueForKey:@name]);

I get the following sample output:

--
{(
foo,
bar,
myPrefix-v1,
myPrefix-v2
)}
--


yup.  Your print statement, though, is not for the objects you  
fetched, but their related books.



These were the four test Book objects I originally associated with one
Owner, and then saved to the managed object context.

I'm unclear why the predicate statement:

@ANY books.name like 'myPrefix*'

would return all books, whether their name starts with 'myPrefix' or
not. The output I would expect is:

--
{(
myPrefix-v1,
myPrefix-v2
)}
--


You're not fetching books, you're fetching Owner.  The predicate   
fetch request pair together to say:


Fetch all the Owners that have ANY (one or more) object in their books  
relationship with a name like 'myPrefix*'


The log statement shows the first Owner in the results array has 2  
books matching your predicate.  It also has a bunch of others, but  
that's irrelevant to whether or not it matches the predicate.  You  
seem to be thinking of this predicate


@ALL books.name like 'myPrefix*'

for which we don't currently generate SQL.

- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: KVO can be unsafe in -init?

2009-09-09 Thread Ben Trumbull

On 08/09/2009, at 12:36 AM, John Chang wrote:


Hi all,
Question: is it unsafe for some reason to be adding yourself as a KVO
observer during -init?

We have a singleton with an -init that looks something like this:
- (id)init
{

if ((self = [super init]))
{

_foo = [[NSMutableDictionary alloc] init];
_bar = [[NSMutableDictionary alloc] init];

[[XYZManager sharedManager] addObserver:self forKeyPath:@allObjects
options:NSKeyValueObservingOptionInitial context:NULL];


As a general rule, in ObjC, C++, and Java it's a very bad idea to  
expose partially constructed objects to third parties, especially via  
global registries like KVO.  In addition to the obvious problems,  
multi-threading and error handling are especially pernicious.  The  
multi-threading issue is pretty self explanatory.  The moment your  
uninitialized object is registered in KVO, others can invoke methods  
on it before you and your subclasses are done setting initial state.


The error handling issue involves what happens when an initializer  
needs to error out.  In Cocoa, it should return nil, and if necessary,  
deallocate its previous self (to prevent +alloc from being unbalanced,  
and hence leak).  But this now means that third parties can reach a  
deallocated object via these registrations.  It will complicate how  
carefully you'll need to write your -dealloc method.


If the KVO registration is the last thing that happens, then it'll  
work, but of course, subclassing will break your assumptions.  This  
falls under the hack category, and is not a pattern you want to  
replicate widely.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Garbage collection and about windows

2009-09-08 Thread Ben Haller
  Hi all.  I'm just getting into my first garbage collected Cocoa  
project, and I'm a bit mystified by the behavior I'm seeing.  I'm just  
trying to make a custom about panel.  I put this method in my  
application delegate:


- (IBAction)orderFrontAboutPanel:(id)sender
{
if (!aboutController)
		aboutController = [[AKAboutPanelController alloc]  
initWithWindowNibName:@AKSplash];


[aboutController showWindow:nil];
}

  I put this declaration of aboutController in my app delegate header:

__weak AKAboutPanelController *aboutController;

And then I implemented AKAboutPanelController like so:

@interface AKAboutPanelController : NSWindowController
{

}
@end

@implementation AKAboutPanelController
- (void)finalize
{
NSLog(@AKAboutPanelController finalize);
[super finalize];
}
@end

  My idea — perhaps being too clever for my own good — was that as  
long as the about window was open, the window would be referenced by  
the window list, and so the window and its controller would stick  
around.  Choosing the About menu item a second time would therefore  
just call showWindow: on the controller again, ordering the window to  
the front if it had gotten buried.  As soon as the window was closed,  
I figured it and its controller would be garbage collected, and the  
weak reference to it in the app delegate would zero out, so then  
choosing About would create a new controller and reload the nib.


  But this is not what happened.

  Instead, the about window sticks around for as long as it is the  
key window (presumably the window is strong-referenced by AppKit or  
somebody at a lower level than the Kit).  As soon as it is not the key  
window (click on a different window in the app) it gets garbage  
collected immediately, even though it is still open!  Now maybe this  
is intended behavior, but it sure isn't what I expected; it seemed  
intuitive to me that an open window, visible to the user, would not be  
garbage collected. Is there a reason that the window list uses weak  
references for visible windows?


  So.  I can think of any number of ways to fix this, of course, but  
they all seem a little bit gross since they involve either tweaking  
the garbage collector (CFRetain, for example) or making the reference  
to the window controller in the app delegate strong, in which it  
doesn't automatically zero and I have to set up a way for the  
windowcontroller to tell the app delegate that it's no longer needed.   
There must be a better pattern; I imagine I'm just not used to  
thinking in garbage-collection terms yet.  So what's the right way to  
do this?


  Thanks...

Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: watch changes to any properties on an object

2009-09-03 Thread Ben Trumbull
Well, @dynamic doesn't have anything to do with KVO.  It's just  
storage and accessors for properties.  Core Data knows when non- 
dynamic modeled properties change too.  It sets a dirty flag, just as  
you would have to.  Most of that happens in -willChangeValueForKey:.   
Unfortunately, overriding that method was deprecated in 10.5.  KVO no  
longer guarantees overrides will be called.


In terms of knowing what to save, Core Data only tracks that at an  
object level, and uses snapshot deltas to compute the changed property  
set at the end.


Some people invert the observing relationship to work around this.   
You can add code in your setters to set a dirty flag, or within your  
setters manually call a notify method on another object.  If you have  
fewer objects, you could just use NSNotifications.


Almost certainly worth filing an enhancement request at bugreport.apple.com

- Ben


Ok, thats what i thought. But just for implementation ideas, how does
CoreData know when one of it's @dynamic properties is changed? It must
set some sort of flag somewhere in order to know what to write out
when it needs to save. How does it handle that?

thx

AC

On Sep 3, 2009, at 12:27 PM, Jens Alfke wrote:



On Sep 3, 2009, at 8:24 AM, Alexander Cohen wrote:


I have a base object that needs to know when any of it's properties
or subclasses properties have changed and set a dirty flag on
itself. Is there a way to do this?


No, not in general. Key-value observing requires knowing the exact
property name(s) in advance. You'll need to set the 'dirty' flag
manually.

˜Jens



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Core Data dog-slow when using first time after boot

2009-09-03 Thread Ben Trumbull


On Sep 3, 2009, at 4:49 AM, Ruotger Skupin wrote:

Since it's not a many to many, you can perform the prefetching  
effectively by hand using a fetch request to preload the relevant  
destination rows with an IN query based on the data you initially  
fetched for the source entity.  You shouldn't have to, but if  
you've run into a bug, that's how you could workaround it.


You still haven't described the NSPredicate you were using with  
filteredArrayUsingPredicate.  Being more forthcoming about the  
context and details of your problem will help us get you answers  
more quickly.
This is the predicate I was using for the test of the original  
post, but since I use Smart Folders predicates can look a lot  
different (i.e.: complex):


(additionalInfo.onTheFlyIsInternal == 0 AND  
additionalInfo.isSuppressed != 1) AND (account.uniqueID IN  
{D1AB3788-00DF-4475-A979-CE3EFC3987B5} OR FALSEPREDICATE)





You'll want to prefetch additionalInfo and account.


Hm. Problem here is: As mentioned I use the predicate for a smart  
group. So the predicate can vary wildly and can reference basically  
any entity in the model. So what is the best strategy here?  
Decompile the predicate (which is built by an NSPredicateEditor)  
and prefetch the keypaths it takes? Prefetch everything?



Prefetching everything is usually undesirable.  The easiest  
approximate solution is to just track the hot button relationships for  
each of your core entities, and look up which keypaths to prefetch by  
entity name.  Of course, you can also do a lot less filtering in  
memory if you pass the predicates to the database with the fetch  
request.  You only need to prefetch relationships you are going to use  
in memory.  You don't need to prefetch anything that's simply used as  
part of the predicate in the fetch request itself.


Walking through the predicate and gathering up the keypaths used is  
very tedious, but not especially difficult, if you find yourself  
wanting a complete solution.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: watch changes to any properties on an object

2009-09-03 Thread Ben Trumbull

On Sep 3, 2009, at 12:14, Alexander Cohen wrote:
Ah, ok, this is more like what i wanted to hear! :) I understand how
@dynamic works, but how to I get to funnel all calls to @dynamic
properties to the same call such as setValue:forKey: or something
like that where i can parse the key and update my internal data and
set the flags i need to set.


No, you're barking up the wrong tree.

There's no how @dynamic works. @dynamic is a compiler directive
telling it that getter/setter method implementations exist, but just
not in the current compilation unit. There no standard general
mechanism for supplying the implementation.

In the case of Core Data specifically, the built-in implementations
(call them dynamic if you want, but that's the same as their being
compiled as @dynamic) are simply efficient versions of what you
would otherwise have to hand-code. We don't know if they're funneled
through one funnel, several funnels, or a different function for every
property -- that's an implementation detail.

(IAC, Core Data doesn't mark objects as changed in *those* dynamic
methods, but (presumably -- another implementation detail) in the
primitiveKey dynamic methods.)

I don't how you're ever going to be able to have a class detect
invocations of its subclasses' properties, unless you have the class
muck around in the runtime, replacing methods on the fly.

A better solution, IMO, is to realize that you're considering a design
requirement for your data model, and to design the solution right into
the model. For example, if this is a self-contained class hierarchy
that you're implementing, you could make it a requirement of
subclasses that they invoke something (a superclass method) or inform
something (a controller of some kind) when they modify data values.


Good advice.

Also, instead of worrying about how Core Data does this, you could  
just leverage Core Data's change tracking, whether via inheritance or  
composition, and respond to the  
NSManagedObjectContextObjectsDidChangeNotification. You don't have to  
save to one of Core Data's persistence mechanisms just to create a  
bunch of managed objects to hold some properties.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Correct way to have nil undo manager in Core Data document?

2009-08-29 Thread Ben Trumbull

Well, I've got a background worker process which opens an
NSPersistenDocument.  Since it has no undo capability, I want to set
it to nil as recommended.  (I have other reasons for not wanting an
undo manager scurrying around.)  But the document doesn't like having
nil undo manager.  When I ask for it later, it creates one for itself,
and sets its managed object context to have the same one.



You need to use the NSDocument API:

/* The document's undo manager. The default implementation of - 
setUndoManager:, in addition to recording the undo manager, registers  
the document as an observer of various NSUndoManager notifications so  
that -updateChangeCount: is invoked as undoable changes are made to  
the document. The default implementation of -undoManager creates an  
undo manager if the document does not already have one and - 
hasUndoManager would return YES. */

- (void)setUndoManager:(NSUndoManager *)undoManager;
- (NSUndoManager *)undoManager;

/* Whether or not the document has an undo manager. The default  
implementation of -setHasUndoManager: releases the document's current  
undo manager if it has one before the invocation but is not to have  
one afterward. */

- (void)setHasUndoManager:(BOOL)hasUndoManager;
- (BOOL)hasUndoManager;


- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Core Data Predicate Builder - comparing dates

2009-08-29 Thread Ben Trumbull

I have a Core Data entity that has a dateCreated and a dateModified -
both NSDates in the object files.
I'd like to construct a predicate that will retrieve all records where
a record's dateModified is greater than that record's dateCreated.

Its deceptively easy to setup something that looks like it should work
using 'Control-click' and 'Key' in the predicate builder in XCode.
But when I run queries it doesn't appear to yield the right results.
My thinking is that the comparison operators don't properly evaluate
dates (am I wrong?)


Comparison operators work just fine on dates, although == and != are  
fragile since NSDates are double time stamps, and floating point  
numbers have odd == behavior.


What does the predicate look like ?  How is it not working ?  What  
does SQL logging show ?



So dropping back to code - how would I write this predicate in code?


[NSPredicate predicateWithFormat:@dateModified  dateCreated]

- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Curious about $SUBST_VARS within a SUBQUERY of a fetch request template

2009-08-29 Thread Ben Trumbull

I just created a fetch request template in my MOM that looked like:
SUBQUERY(platformInfos, $each, $each.platformName ==
$PLATFORM_NAME)@count == 0

I then looked up the template in the code and attempted to use it in  
the

usual manner with:
fetchRequestFromTemplateWithName:substitutionVariables:


should work


Core Data complained that it could not resolve the SQL for
$each.platformName == $PLATFORM_NAME, because of the RHS.

I would have thought that this variable would be replaced as normal,  
even
though it is inside a SUBQUERY.  Does anybody know if this is  
officially

disallowed, or a bug, or just developer-error somehow?


What your code look like for the substitution variables dictionary ?

- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: core-data app design question

2009-08-29 Thread Ben Trumbull

I have a question, or rather, I'm looking for advice, on the design of
an application. Essentially I'm wanting to write a labbook-type
application. My plan was to use core-data for the model. In the model
will be an Entry entity. Each entry will have a one-to-one
relationship to a Content entity. The Content entity will just (at the
moment) contain a single attribute (data) which will be binary data.
Implementing this on the Mac I planned to use NSTextView to provide a
rich-text entry for the data attribute. Now comes the problem. I want
to make a Cocoa Touch version of the app, and make then synchronize
over Mobile me. The problem is I see no way to handle the
NSAttributedString that will be stored in the data attribute on the
iPhone.

Does anyone have any advice as to how I might go about this? I was
considering dropping back to plain text, but am loath to do this.


Well, since you can't draw NSAttributedStrings on the iPhone, there  
isn't much point in archiving your data that way.  You should use a  
platform neutral text run.  You can write your own, which isn't hard  
for basic attributes, or you can use HTML instead, which you can draw  
on both platforms easily.


Encoding your data this way is pushing the boundaries of violating MVC  
patterns by archiving UI information (NSTextView drawing information)  
into your model (database).  That obviously doesn't work if the  
platform doesn't support NSTextView.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Core Data observer exception in 10.6

2009-08-29 Thread Ben Trumbull

In a Core Data-based app that works fine in 10.5.x, I now get an
exception as follows in 10.6 when opening a document.  It targets
10.5, and the same exception occurs when rebuilding on 10.6 (still
targeting 10.5, but also when targeting 10.6).

I don't register or unregister any observers myself, and the exception
occurs without touching any of my code.  What's going on?


NSRangeException: Cannot remove an observer NSKeyValueObservance
0x15476c0 for the key path richText from TextEntity 0x1546380
because it is not registered as an observer.
 1	+[NSException raise:format:arguments:] (in CoreFoundation) +  
136

 2  +[NSException raise:format:] (in CoreFoundation) + 58
 3  -[NSObject(NSKeyValueObserverRegistration)
_removeObserver:forProperty:] (in Foundation) + 765
 4  -[NSObject(NSKeyValueObserverRegistration)
removeObserver:forKeyPath:] (in Foundation) + 176
 5  -[NSKeyValueNestedProperty
object:didRemoveObservance:recurse:] (in Foundation) + 544
 6  -[NSObject(NSKeyValueObserverRegistration)
_removeObserver:forProperty:] (in Foundation) + 453
 7  -[NSObject(NSKeyValueObserverRegistration)
removeObserver:forKeyPath:] (in Foundation) + 176
 8  -[_NSModelObservingTracker
_registerOrUnregister:observerNotificationsForModelObject:] (in
AppKit) + 228
 9  -[_NSModelObservingTracker clearAllModelObjectObserving] (in
AppKit) + 341
10  -[_NSModelObservingTracker
setIndexReferenceModelObjectArray:clearAllModelObjectObserving:] (in
AppKit) + 51
11  -[NSArrayController _setObjects:] (in AppKit) + 196
12  -[NSArrayController
_arrangeObjectsWithSelectedObjects:avoidsEmptySelection:operationsMask:useBasis
:] (in AppKit) + 510
13  -[NSArrayController rearrangeObjects] (in AppKit) + 133
14  -[NSArrayController
observeValueForKeyPath:ofObject:change:context:] (in AppKit) + 338
15  NSKeyValueDidChange (in Foundation) + 377
16  -[NSObject(NSKeyValueObservingPrivate)
_didChangeValuesForKeys:] (in Foundation) + 565
17  _PFFaultHandlerFulfillFault (in CoreData) + 1921
18  _PFFaultHandlerLookupRow (in CoreData) + 1573
19  -[NSFaultHandler fulfillFault:withContext:] (in CoreData) + 39
20  _PF_FulfillDeferredFault (in CoreData) + 193
21  _sharedIMPL_pvfk_core (in CoreData) + 65
22  -[NSManagedObject(_PFDynamicAccessorsAndPropertySupport)
_genericValueForKey:withIndex:flags:] (in CoreData) + 79
23  -[NSManagedObject valueForKey:] (in CoreData) + 244
24  -[NSKeyValueNestedProperty object:didAddObservance:recurse:]
(in Foundation) + 240
25  -[NSObject(NSKeyValueObserverRegistration)
_addObserver:forProperty:options:context:] (in Foundation) + 812
26  -[NSObject(NSKeyValueObserverRegistration)
addObserver:forKeyPath:options:context:] (in Foundation) + 565
27  -[_NSModelObservingTracker
_registerOrUnregister:observerNotificationsForKeyPath:ofModelObject:]
(in AppKit) + 134
28  -[_NSModelObservingTracker
_registerOrUnregister:observerNotificationsForModelObject:] (in
AppKit) + 228
29  -[_NSModelObservingTracker _startObservingModelObject:] (in
AppKit) + 418
30  -[_NSModelObservingTracker
startObservingModelObjectsAtReferenceIndexes:] (in AppKit) + 333
31  -[NSArrayController
_arrangeObjectsWithSelectedObjects:avoidsEmptySelection:operationsMask:useBasis
:] (in AppKit) + 510
32  -[NSArrayController setContent:] (in AppKit) + 889
33  -[NSArrayController(NSManagedController)
_performFetchWithRequest:merge:error:] (in AppKit) + 501
34  -[NSObjectController(NSManagedController)
fetchWithRequest:merge:error:] (in AppKit) + 209
35  -[NSObjectController(NSManagedController)
_executeFetch:didCommitSuccessfully:actionSender:] (in AppKit) + 106
36  _NSSendCommitEditingSelector (in AppKit) + 339
37  -[NSController _controllerEditor:didCommit:contextInfo:] (in
AppKit) + 216
38  __invoking___ (in CoreFoundation) + 29
39  -[NSInvocation invoke] (in CoreFoundation) + 136
40  -[NSInvocation invokeWithTarget:] (in CoreFoundation) + 72
41  __NSFireDelayedPerform (in Foundation) + 537
42  __CFRunLoopRun (in CoreFoundation) + 6846


Hard to say without more details, but it does look like a Cocoa  
Bindings bug.  If you could create a new sample project with your NIB  
and your model and reproduce this, and then attach it to a bug report,  
that would be extremely helpful.


Thanks,

- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: CoreData: Using to-may relationships in fetch request predicates

2009-08-29 Thread Ben Trumbull

in  the typical CoreData example, if I want to fetch all departments
whose employees have a salary higher than a specified value, I will
perform a fetch on the Department entity using a predicate with the
following format:

ANY employees.salary  %@

This is working fine.
Now I want to fetch all departments whose employees fulfill the salary
condition AND are born after a certain date. I would expect something
like this to work:

ANY (employees.salary  %@ AND employees.dateOfBirth  %@

But it doesn't. Does anybody know if there is a way to use the ANY
statement with more than one condition?


You'll need to use a SUBQUERY predicate instead of an ANY/operator.   
Probably easiest to do SUBQUERY(..)@count  0


Please file a bug.

- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Auto complete accepts on space, any way to change?

2009-08-28 Thread Ben Lachman
My app, SousChef, uses the AppKit autocomplete functionality in a  
bunch of places.  Currently if a user types So they are presented  
with a list of completions and the first actual completion (Soup) is  
used inline and selected so that this completed part is used if the  
user tabs to the next item but isn't if the user keeps typing (e.g.  
up is selected, So is not).  However in recently we've noticed  
that if you are typing through an autocomplete and hit space, the  
current completion is accepted and the space is appended to it.  This  
is unwanted behavior.  However in Safari's location bar, which has the  
functionality I want, if you hit space, the space is appended to the  
partial word instead of the full completion.  Anyone have an idea of  
how to get this behavior of just accepting on enter/tab (cancel on  
escape already works)?  Currently I'm only implementing - 
textView:completionsForPartialWordRange:indexOfSelectedItem:.  I  
thought to override keyDown: but the problem is that the field editor  
is eating keystrokes.


Thanks,
-Ben
--
Ben Lachman
Acacia Tree Software

http://acaciatreesoftware.com

email: blach...@mac.com
twitter: @benlachman
mobile: 740.590.0009



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Core Data dog-slow when using first time after boot

2009-08-25 Thread Ben Trumbull


On Aug 25, 2009, at 7:19 AM, Ruotger Skupin wrote:



Am 24.08.2009 um 23:13 schrieb Ben Trumbull:


When I use setRelationshipKeyPathsForPrefetching the fetch throws:

-[NSSQLAttribute inverseRelationship]: unrecognized selector sent  
to instance 0x10ee150


Can you provide the entire stack trace at this point ?  gdb use  
future-break objc_exception_throw





Thanks.  What is the actual set of keypaths you set in the fetch  
request ?  setRelationshipKeyPathsForPrefetching expects all the  
keypaths to terminate in a relationship object, not the attribute off  
that related object.



(this is 10A432)




For the record: I do use one-way relationships



That should be okay as long as you're not pretending to use a no  
inverse to-many relationship as a de facto many to many  
relationship.  No inverse relationships can only behave as if the  
inverse were to-one.  Specifically, each row in the destination  
entity may only be associated with a single row in the source  
entity if the relationship on the source entity does not have an  
inverse.  (e.g. you only get join tables in fully modeled bi- 
directional relationships)
Do I understand that correctly? No two (or more) Accounts or  
Transactions should point to the same Amount (see simplified  
schema). Unless there's a bug somewhere that's not the case.


Correct.  For each separate modeled no inverse relationship, the  
destination row (Amount) can only be pointed to by one source row.




|-|
| Transaction |
|-| ||
|net  | -- | Amount | -- (one other entity)
|gross| -- ||
|fee  | -- |value   | -
|account  | - |currency||
|...  |||||
|-||  |
   |  |
 --   |
| |
|||   |
|| Account|   |
|||   |
||balances| --
 -- |transactions|
 |... |
 ||

So basically I use Amount only as a container for a currency  
descriptor and a value. I would have to model 7 inverse  
relationships on that entity to make all relationships two-way.


Hmm.  I'd recommend consider whether or not it makes sense to de- 
normalize Amount into Transaction instead of making it a separate  
entity.  I assume the net/gross/fee are all going to be in the same  
currency, yes ?  Amount is very fine grained, and not (apparently)  
offering very much value for the abstraction cost.






Since it's not a many to many, you can perform the prefetching  
effectively by hand using a fetch request to preload the relevant  
destination rows with an IN query based on the data you initially  
fetched for the source entity.  You shouldn't have to, but if  
you've run into a bug, that's how you could workaround it.


You still haven't described the NSPredicate you were using with  
filteredArrayUsingPredicate.  Being more forthcoming about the  
context and details of your problem will help us get you answers  
more quickly.
This is the predicate I was using for the test of the original post,  
but since I use Smart Folders predicates can look a lot different  
(i.e.: complex):


(additionalInfo.onTheFlyIsInternal == 0 AND  
additionalInfo.isSuppressed != 1) AND (account.uniqueID IN  
{D1AB3788-00DF-4475-A979-CE3EFC3987B5} OR FALSEPREDICATE)





You'll want to prefetch additionalInfo and account.

- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Core Data dog-slow when using first time after boot

2009-08-24 Thread Ben Trumbull


On Aug 24, 2009, at 3:20 AM, Ruotger Skupin wrote:



Am 20.08.2009 um 22:28 schrieb Ben Trumbull:


setRelationshipKeyPathsForPrefetching


When I use setRelationshipKeyPathsForPrefetching the fetch throws:

-[NSSQLAttribute inverseRelationship]: unrecognized selector sent to  
instance 0x10ee150


Can you provide the entire stack trace at this point ?  gdb use future- 
break objc_exception_throw



For the record: I do use one-way relationships



That should be okay as long as you're not pretending to use a no  
inverse to-many relationship as a de facto many to many relationship.   
No inverse relationships can only behave as if the inverse were to- 
one.  Specifically, each row in the destination entity may only be  
associated with a single row in the source entity if the relationship  
on the source entity does not have an inverse.  (e.g. you only get  
join tables in fully modeled bi-directional relationships)


Since it's not a many to many, you can perform the prefetching  
effectively by hand using a fetch request to preload the relevant  
destination rows with an IN query based on the data you initially  
fetched for the source entity.  You shouldn't have to, but if you've  
run into a bug, that's how you could workaround it.


You still haven't described the NSPredicate you were using with  
filteredArrayUsingPredicate.  Being more forthcoming about the context  
and details of your problem will help us get you answers more quickly.


- Ben

___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


re: Using Core Data NSManagedObject subclasses outside of a managed object context

2009-08-24 Thread Ben Trumbull
I have objects that I use with core data that were automatically  
generated
for me by xcode and represent entities in my data store. They all  
subclass
NSManagedObject, and do not have instance variables, but instead use  
the
@dynamic setting for their properties, pretty standard. My  
understanding is

that this allows the NSManagedObject superclass to generate the
getters/setters at runtime and store data in it's own, more  
efficient, Core

Data friendly way.


yup

What this means for me, however, is that I can't just call [[Entity  
alloc]

init] and then get/set Entity's properties, because it won't properly
initialize unless it is given a managed object context. I need to be  
able to
use my objects in places that they won't be persisted, as just  
transient
objects, but this prevents that. The only way I know to initialize  
them is

by calling [NSEntityDescription insertNewObjectForEntityForName:name
inManagedObjectContext:managedObjectContext] . But, when creating  
objects

this way, they will be persisted on the next save call.


There's no requirement that you put them in the same  
NSManagedObjectContext that you call save: on.  You can just create a  
second transient MOC.  Alternatively, you can add an in-memory store  
to your NSPersistentStoreCoordinator and assign the newly inserted  
objects to that store with -assignObject:toPersistentStore: and then  
they'll get saved to an in memory backing store. This is probably  
easier to manage, and definitely provides more features than the  
second MOC approach.  It does do a touch more work, though.



Just so you know, I'm making a feed reader that has the option to save
selected stories from the feed for later, offline, browsing. I want  
to be
able to download the feed XML and create 'story' objects from that  
without

having to persist every story I fetch.


Regardless of approach, you'll need to copy the transient objects into  
new persistent objects to individually change their nature from  
transient to normal managed objects.


- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: When do I need to override hash?

2009-08-21 Thread Ben Trumbull


On Aug 20, 2009, at 9:09 PM, Jeff Laing wrote:


If you need to know whether or not another object has put your object
into an NSDictionary, you're probably doing something wrong.  Do you
have a specific concern about Core Data using your objects ?


No, I guess the point I was trying to make was that this discussion  
seemed to have touched on if you put your objects into an NSSet  
then you'll need to be more careful about the implementation of - 
hash, etc.  I was trying to point out that just because my  
application code doesn't go anywhere near NSSet, its conceivable (to  
me) that Core Data (for example) might be storing dirty objects in  
an NSSet behind your back. So you can't not implement -hash, etc  
properly and hope everything will work.


There may be any number of external technologies (Core Data was  
just an example) that may be using your objects in ways you aren't  
expecting, and there's no future-proof way you can cut corners.


There really isn't any point in cutting corners here.  If you need to  
do something unusual, you can use a CFDictionary with custom callbacks.


- Ben



___

Cocoa-dev mailing list (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


<    1   2   3   4   5   6   7   >