Re: Core Data and ARC crasher and workaround

2012-04-18 Thread Michael Link
I'm running into a similar situation except it's not crashing at the time of 
dealloc but at some later time. Here's the rundown of what I see happening.

1. Global parent (non main-thread MOC) is alloc'd
2. Child1 (main-thread) MOC is alloc'd
3. Child2 (main-thread) MOC is alloc'd
4. Child1 MOC is dealloc'd

At this point it seems something clobbers Child2's reference to its parent MOC 
so anything you try to do with it that needs to access the parent MOC causes a 
crash.

Dealloc: Block address: 0x0f46ba90
Stack - pthread: 0xb0457000 number of frames: 9
0: 0x99629d4d in free
1: 0x27ea01d in object_dispose
2: 0x16ff184 in NSDeallocateObject
3: 0x1d4561f in internalBlockToDeallocNSManagedObjectContext
4: 0x299bf0c in _dispatch_queue_drain
5: 0x299bcb4 in _dispatch_queue_invoke
6: 0x299b402 in _dispatch_worker_thread2
7: 0x995d6b24 in _pthread_wqthread
8: 0x995d86fe in start_wqthread

The dealloc happens on a different thread than what it was created on.

This is strange because the parent MOC shouldn't be dealloc'd, it's referenced 
by the app delegate and also a global variable.

I can reproduce the problem every time. If I change the optimization level from 
-Os to -O0 the problem goes away. Could be a bug in clang/ARC.

--
Michael


On Apr 3, 2012, at 12:46 PM, Zac Bowling wrote:

 So I'm running into a crasher in iOS 5.0 and iOS 5.1 when using ARC with Core 
 Data and wanted to warn everyone and give a possible fix. I'm filing radar on 
 this but wanted to push it out there to list because it took me a while to 
 track down exactly what the issue was from the crazy stack trace. 
 
 The crash happens below the dealloc and cxx_destruct method (that gets called 
 by ARC) in a method named something around decrementing references to a 
 managed object in the persistent store. 
 
 I've narrowed it down though.
 
 If you have a NSManagedObjectContext reference in an object that is 
 controlled by ARC and you have an NSManagedObject that is a member of that of 
 that context that is also referenced by that same ARC controlled object, and 
 you deference that object and it deallocs, if ARC deferences the 
 NSManagedObjectContext before the NSManagedObject (the order is not 
 determinate of releases unfortunately) and releases both about the same time 
 in the same dealloc call, you will get a crash deep down inside core data. 
 
 This only happens when the context and the object references are released 
 about the same time by ARC. I can't reproduce this without ARC. 
 
 If you override dealloc and do something like this it will take care of it 
 (assuming you didn't have that context referenced anywhere else). 
 
 -(void) dealloc { 
   [_managedObjectContext reset];
 }
 
 This also seemed to work but it's hard in our cases because references are 
 held by our child objects in many cases and it's not easy to always know who 
 still my have a reference. 
 
 -(void) dealloc { 
   _objectFromContext = nil;
   _managedObjectContext = nil;
 }
 
 
 I've also had this problem inside a single function scope where the context 
 is dealloc at the end of the function. Nesting the references to the objects 
 from that context in lower scopes or in blocks so the NSManagedObject 
 references get dealloc'd before the context does solves the problem.
 
 This is totally a hunch but I believe this is because of the magic with 
 tagged pointers introduced with Lion possible and them not playing nice with 
 ARC and the core data code. 
 http://objectivistc.tumblr.com/post/7872364181/tagged-pointers-and-fast-pathed-cfnumber-integers-in
  . I think fault objects don't have a well defined strong reference to the 
 context when they are not really there (just virtual tagged pointers) and I 
 think optimizations in the ARC generated dealloc code get borked. Pure 
 speculation but there is a lot of magic optimizations going on here now that 
 may not be playing well together. 
 
 I think that many people don't run into this issue because they leave their 
 contexts around for long periods and if they are making short lived ones they 
 might not being using ARC. With parent/child contexts we create child 
 contexts all the time to scope changed and NSUndoManagers to our modal 
 popovers that have their own explicit save. 
 
 Here is the stack trace for google points and those that are curious: 
 
 EXC_BAD_ACCESS
 
 #0 0x02475098 in objc_msgSend ()
 #1 0x009e57f0 in _PFObjectIDFastHash64 ()
 #2 0x020488a0 in __CFDictionaryHashKey ()
 #3 0x01f9e0e4 in CFBasicHashFindBucket ()
 #4 0x01f9daa5 in CFDictionaryGetValue ()
 #5 0x009fde6a in -[NSPersistentStoreCache decrementRefCountForObjectID:] ()
 #6 0x009fddf4 in -[NSSQLCore 
 managedObjectContextDidUnregisterObjectsWithIDs:] ()
 #7 0x00ab9fb6 in -[NSPersistentStoreCoordinator(_NSInternalMethods) 
 _informAffectedStoresOfInterestByChildContextInObjectsWithObjectIDs:withSelector:]
  ()
 #8 0x009fdcff in -[NSPersistentStoreCoordinator(_NSInternalMethods) 
 

Core Data nested managed object contexts and frequent deadlocks

2012-01-13 Thread Michael Link
I have a parent MOC setup with NSPrivateQueueConcurrencyType and a persistent 
store coordinator set, it has a child MOC setup with 
NSMainQueueConcurrencyType. The idea being most of the long hard work and saves 
can be done on the private MOC freeing the main thread from blocking the UI. 
Unfortunately I seem to be running into a couple of situations that cause 
deadlocks.

If the child MOC (on the main thread) is faulting in an object and the parent 
context is sent an -executeFetchRequest: or -save: it always deadlocks. Both 
operations are done within the context of a performBlock: for their respective 
MOCs although the docs seem to indicate that using a main thread concurrency 
type MOC on the main thread without performBlock: is fine.

It appears that the private queue is waiting on the PSCs lock which the child 
context on the main thread has already locked. It appears that the child 
context (while holding the PSCs lock) is trying to dispatch_sync to the parent 
context and thus they are both waiting for each other. 

Is PriveQueue - MainQueue a supported configuration? It seems most people 
still have the parent context on the main thread.

The main thread looks like this:

#0  0x960f6c5e in semaphore_wait_trap ()
#1  0x04956bb5 in _dispatch_thread_semaphore_wait ()
#2  0x04955c8f in _dispatch_barrier_sync_f_slow ()
#3  0x04955dea in dispatch_barrier_sync_f ()
#4  0x01797de5 in _perform ()
#5  0x01798547 in -[NSManagedObjectContext(_NestedContextSupport) 
newValuesForObjectWithID:withContext:error:] ()
#6  0x0176416b in _PFFaultHandlerLookupRow ()
#7  0x01763f97 in -[NSFaultHandler fulfillFault:withContext:forIndex:] ()
#8  0x01763b75 in _PF_FulfillDeferredFault ()
#9  0x017639f2 in _sharedIMPL_pvfk_core ()
#10 0x017681a0 in _pvfk_11 ()
#11 0x0001b322 in -[FBUser sectionName] at /Users/mlink/Code/x/x/FBUser.m:62
#12 0x011a8813 in _NSGetUsingKeyValueGetter ()
#13 0x017a0652 in -[NSManagedObject valueForKey:] ()
#14 0x011ab8d5 in -[NSObject(NSKeyValueCoding) valueForKeyPath:] ()
#15 0x01851f72 in -[NSFetchedResultsController(PrivateMethods) 
_sectionNameForObject:] ()
#16 0x01853af6 in -[NSFetchedResultsController(PrivateMethods) 
_computeSectionInfo:error:] ()
#17 0x01850ea6 in -[NSFetchedResultsController performFetch:] ()
#18 0x0003a4fc in __62-[SYFriendsTableViewController 
updateFetchedResultsController]_block_invoke_0 ()
#19 0x01797af3 in developerSubmittedBlockToNSManagedObjectContextPerform ()
#20 0x049554f0 in _dispatch_main_queue_callback_4CF ()
#21 0x01b3e833 in __CFRunLoopRun ()
#22 0x01b3ddb4 in CFRunLoopRunSpecific ()
#23 0x01b3dccb in CFRunLoopRunInMode ()
#24 0x023d6879 in GSEventRunModal ()
#25 0x023d693e in GSEventRun ()
#26 0x0089aa9b in UIApplicationMain ()
#27 0x2656 in main at /Users/mlink/Code/x/x/main.mm:16

the private queue stack looks like this:

#0  0x960f8876 in __psynch_mutexwait ()
#1  0x97e9e6af in pthread_mutex_lock ()
#2  0x0172ec22 in -[_PFLock lock] ()
#3  0x0172ebfa in -[NSPersistentStoreCoordinator lock] ()
#4  0x01746a8c in -[NSManagedObjectContext(_NSInternalAdditions) 
lockObjectStore] ()
#5  0x01745030 in -[NSManagedObjectContext executeFetchRequest:error:] ()
#6  0x0009d49f in -[NSManagedObjectContext(Additions) executeFetchRequest:] 
at /Users/mlink/Code/objc/C/C/NSManagedObjectContext+Additions.m:44
#7  0x0002177f in +[FBUser usersForFbids:inManagedObjectContext:] at 
/Users/mlink/Code/x/x/FBUser.m:435
#8  0x00021fc0 in __77+[FBUser 
updateUserFromGraphValues:inManagedObjectContext:completionHandler:]_block_invoke_0
 at /Users/mlink/Code/x/x/FBUser.m:461
#9  0x0180f9f3 in 
developerSubmittedBlockToNSManagedObjectContextPerform_privateasync ()
#10 0x04954ecf in _dispatch_queue_drain ()
#11 0x04954d28 in _dispatch_queue_invoke ()
#12 0x049544af in _dispatch_worker_thread2 ()
#13 0x97ea1b24 in _pthread_wqthread ()
#14 0x97ea36fe in start_wqthread ()

___

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 nested managed object contexts and frequent deadlocks

2012-01-13 Thread Michael Link

On Jan 13, 2012, at 3:45 PM, Chris Hanson wrote:

 On Jan 13, 2012, at 12:39 AM, Michael Link wrote:
 
 the docs seem to indicate that using a main thread concurrency type MOC on 
 the main thread without performBlock: is fine.
 
 It is, otherwise you couldn't (say) bind to a managed object you fetched via 
 a main-queue context on OS X.  What OS version(s) are you seeing this with?

iOS 5.0 on simulator and iOS 5.0.1 on iPhone.

 
 It appears that the private queue is waiting on the PSCs lock which the 
 child context on the main thread has already locked. It appears that the 
 child context (while holding the PSCs lock) is trying to dispatch_sync to 
 the parent context and thus they are both waiting for each other. 
 
 Is PriveQueue - MainQueue a supported configuration? It seems most people 
 still have the parent context on the main thread.
 
 Using a parent private-queue context and a child main-queue context is 
 actually a good design.  I'm not sure about your deadlock; does it still 
 occur if you don't use -performBlock: on your main-queue context but just 
 interact with it directly?

Yes, in exactly the same way. I'm starting to think the problem is with 
NSFetchedResultsController which is always stuck at performFetch: when these 
deadlocks occur. Most of the time it will be stuck trying to fault in an object 
as a result of asking for it's section name. As a test I tried to reproduce 
what the FRC does and performed the executeFetchRequest: and then iterated 
through the results asking each object for it's section name. And this doesn't 
cause a deadlock. If I leave the FRC to do performFetch: after I do my test it 
will still deadlock there. I'm 99% sure that the FRC has a synchronization 
problem with nested contexts.

--
Michael___

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


NSURLConnection using setDelegateQueue deadlocks

2011-12-19 Thread Michael Link
Is there some trick to getting NSURLConnection to work with an NSOperationQueue 
on iOS 5, and perhaps Lion but I haven't tried it there? It seems that it 
causes a deadlock every time just after the last delegate message has been sent 
(connectionDidFinishLoading:). The project is using ARC.

The connection is setup like this:

_connection = [[NSURLConnection alloc] initWithRequest:request delegate:self 
startImmediately:NO];
[_connection setDelegateQueue:_queue];
[_connection start];

The operation queue used is setup in this category method of NSOperationQueue

+ (NSOperationQueue*)URLConnectionQueue
{
static NSOperationQueue* _S_operationQueue;
static dispatch_once_t _S_once;

dispatch_once(_S_once, ^{
_S_operationQueue = [[NSOperationQueue alloc] init];
_S_operationQueue.name = 
@com.falkor.URLConnectionQueuedLoading;
});

return _S_operationQueue;
}

The connection runs and finishes sending the connectionDidFinishLoading: 
message and then deadlocks on the thread that created it. Interestingly enough 
it appears that a runloop is still required to even start the connection when 
it's setup to use a NSOperationQueue for the delegate messages otherwise the 
connection is never started.

Thread 7 (process 22301):
#0  0x960f8b42 in select$DARWIN_EXTSN ()
#1  0x017107fb in __CFSocketManager ()
#2  0x97e9fed9 in _pthread_start ()
#3  0x97ea36de in thread_start ()

Thread 6 (process 22301):
#0  0x960f6c22 in mach_msg_trap ()
#1  0x960f61f6 in mach_msg ()
#2  0x0177c13a in __CFRunLoopServiceMachPort ()
#3  0x016df605 in __CFRunLoopRun ()
#4  0x016dedb4 in CFRunLoopRunSpecific ()
#5  0x016deccb in CFRunLoopRunInMode ()
#6  0x00e2de40 in +[NSURLConnection(Loader) _resourceLoadLoop:] ()
#7  0x00d3f4e6 in -[NSThread main] ()
#8  0x00d3f457 in __NSThread__main__ ()
#9  0x97e9fed9 in _pthread_start ()
#10 0x97ea36de in thread_start ()

Thread 5 (process 22301):
#0  0x960f8876 in __psynch_mutexwait ()
#1  0x97e9e6af in pthread_mutex_lock ()
#2  0x0216b7e1 in URLConnectionClient::cancelConnection ()
#3  0x0209cc0c in URLConnection::cancel ()
#4  0x0209cbf2 in CFURLConnectionCancel ()
#5  0x00e2fdca in -[NSURLConnectionInternalConnection _invalidate] ()
#6  0x00e2ed10 in __66-[NSURLConnectionInternal 
_withConnectionDisconnectFromConnection]_block_invoke_0 ()
#7  0x00e2ee94 in __65-[NSURLConnectionInternal 
_withConnectionAndDelegate:onlyActive:]_block_invoke_0 ()
#8  0x00d6b64e in -[NSBlockOperation main] ()
#9  0x00d641f7 in -[__NSOperationInternal start] ()
#10 0x00d63efa in -[NSOperation start] ()
#11 0x00df40bd in __block_global_6 ()
#12 0x02487445 in _dispatch_call_block_and_release ()
#13 0x024884e6 in _dispatch_worker_thread2 ()
#14 0x97ea1b24 in _pthread_wqthread ()
#15 0x97ea36fe in start_wqthread ()

Thread 4 (process 22301):
#0  0x960f6c22 in mach_msg_trap ()
#1  0x960f61f6 in mach_msg ()
#2  0x0177c13a in __CFRunLoopServiceMachPort ()
#3  0x016df605 in __CFRunLoopRun ()
#4  0x016dedb4 in CFRunLoopRunSpecific ()
#5  0x016deccb in CFRunLoopRunInMode ()
#6  0x057cd220 in RunWebThread ()
#7  0x97e9fed9 in _pthread_start ()
#8  0x97ea36de in thread_start ()

Thread 3 (process 22301):
#0  0x960f883e in __psynch_cvwait ()
#1  0x97ea3e21 in _pthread_cond_wait ()
#2  0x97e5442c in pthread_cond_wait$UNIX2003 ()
#3  0x00d7a8fc in -[__NSOperationInternal waitUntilFinished] ()
#4  0x00d7a85e in -[NSOperation waitUntilFinished] ()
#5  0x00e2ff0e in -[NSURLConnectionInternalConnection invokeForDelegate:] ()
#6  0x00e2ee4f in -[NSURLConnectionInternal 
_withConnectionAndDelegate:onlyActive:] ()
#7  0x00e2ecb0 in -[NSURLConnectionInternal 
_withConnectionDisconnectFromConnection] ()
#8  0x00d73fe2 in _NSURLConnectionReleaseClient ()
#9  0x0216b306 in URLConnectionClient::releaseClientLocked ()
#10 0x0209342d in URLConnectionClient::processEvents ()
#11 0x0216916b in non-virtual thunk to 
URLConnectionInstanceData::multiplexerClientPerform() ()
#12 0x02093137 in MultiplexerSource::perform ()
#13 0x0177c97f in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ ()
#14 0x016dfb73 in __CFRunLoopDoSources0 ()
#15 0x016df454 in __CFRunLoopRun ()
#16 0x016dedb4 in CFRunLoopRunSpecific ()
#17 0x016deccb in CFRunLoopRunInMode ()
#18 0x00d7341f in -[NSRunLoop(NSRunLoop) runMode:beforeDate:] ()
#19 0xe723 in -[FBLoginOperation main] (self=0xfa19a90, _cmd=0x166971a) at 
LoginOperation.m:142
#20 0xe542 in -[FBLoginOperation start] (self=0xfa19a90, _cmd=0x6aadf8b) at 
LoginOperation.m:127
#21 0x00df40bd in __block_global_6 ()
#22 0x02487445 in _dispatch_call_block_and_release ()
#23 0x024884e6 in _dispatch_worker_thread2 ()
#24 0x97ea1b24 in _pthread_wqthread ()
#25 0x97ea36fe in start_wqthread ()

Thread 2 (process 22301):
#0  0x960f990a in kevent ()
#1  0x02489373 in _dispatch_mgr_invoke ()
#2  0x02487cd0 in _dispatch_mgr_thread ()

Thread 1 (process 22301):
#0  0x960f6c22 in mach_msg_trap ()
#1  0x960f61f6 in mach_msg ()
#2  

drag and drop not working between windows on 10.7

2011-08-30 Thread Michael Link
I have a document based app that has a source list (NSOutlineView) that allows 
drag and drop on itself or another source list (same class) in a different 
document in the same application.

Everything works on 10.6, in 10.7 drags to the same NSOutlineView are validated 
as I expect. Drags to the other source list in a different document (different 
window) are momentarily validated but then immediately invalidated. I can 
confirm that 

- (NSDragOperation)outlineView:(NSOutlineView*)outlineView validateDrop:(id 
NSDraggingInfo)info proposedItem:(id)item proposedChildIndex:(NSInteger)index

is returning the correct operation (copy), but for some reason it doesn't 
stick. Is there some side effect of the new dragging sessions that might be 
causing this? I don't see any other delegate methods that would interfere with 
the drag operation like this.

--
Michael___

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


CALayers are rooted in GC only apps

2011-07-09 Thread Michael Link
In an application that is built gc-only it seems that any CALayers added as 
sublayers to an NSView are rooted (perhaps by CFRetain) and if those layers 
have any references to the NSView that is hosting them then they can cause a 
memory leak.

I have a view that has sublayers that accept completion blocks for actions on 
mouse clicks. If the block references the view then when the window is closed 
(set to release when closed) the window, view ect are retained because the 
layer is rooted.

When running in instruments it is telling me that the layer has a Non-zero CF 
retain count and that's why it is rooted. Why would it need to be rooted in a 
gc-only app though? Shouldn't there be strong references instead? Is there a 
way to un-root the layer if it's not necessary for it to be rooted?

rdar://problem/9749825

--
Michael___

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


Core Data: stop object from firing fault?

2011-06-30 Thread Michael Link
Is there anyway to stop an NSManagedObject from firing a fault, say because 
it's actually been deleted?

For instance if an object is created on the main thread and is then punted to a 
background thread and deleted (in a separate context of course) then the 
changes are merged back to the main thread, the reference on the main thread 
shows it's now a fault, but not that it's deleted. If the object fires its 
fault then of course an exception is raised.

Does anyone know a way to change this behavior so that you can test if an 
object is invalid?

--
Michael___

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 migration opens ~ file by mistake

2011-03-21 Thread Michael Link
I'm running into this same problem on 10.6 when the migration is automatic or 
manual. I can always reproduce it with manual migration.

After migration and the document window is open and the application is made 
inactive and active again you may notice the title of the document has suddenly 
changed to the backup file with the ~ before the extension. It appears that the 
magic file watching behavior of NSDocument decides to switch back to the backup 
file which typically causes unexpected behavior.

#0  0x12fb9 in -[MyDocument setFileURL:] at MyDocument.m:556
#1  0x7fff80b0fdcc in -[NSDocument _handleDocumentFileChanges:]
#2  0x7fff887c67b4 in -[NSArray makeObjectsPerformSelector:withObject:]
#3  0x7fff8329523c in __NSFireDelayedPerform
#4  0x7fff887b1be8 in __CFRunLoopRun
#5  0x7fff887afdbf in CFRunLoopRunSpecific
#6  0x7fff854cc93a in RunCurrentEventLoopInMode
#7  0x7fff854cc69d in ReceiveNextEventCommon
#8  0x7fff854cc5f8 in BlockUntilNextEventMatchingListInMode
#9  0x7fff80939e64 in _DPSNextEvent
#10 0x7fff809397a9 in -[NSApplication 
nextEventMatchingMask:untilDate:inMode:dequeue:]
#11 0x7fff808ff48b in -[NSApplication run]
#12 0x7fff808f81a8 in NSApplicationMain
#13 0x1e7f5 in main at main.m:27

I've fixed this in my manual migration by using FSExchangeObjects(). 
Unfortunately the docs say that it only works on HFS+ and AppleShares... and 
perhaps you don't like to make assumptions about where people store their data.

I've also fixed this by using NSFileManager's 
-replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:

This appears to work if you don't use the 
NSFileManagerItemReplacementWithoutDeletingBackupItem option. If you do then 
you will need to know where the backup file is located and add this method to 
your NSDocument subclass.

- (void)setFileURL:(NSURL*)absoluteURL
{
if ([absoluteURL isEqual:_backupURL]) {
[super setFileURL:[self fileURL]];
return;
}

[super setFileURL:absoluteURL];
}

--
Michael

On Feb 22, 2011, at 10:36 PM, Jim Thomason wrote:

 I'm finally trying to do my first CoreData migration using the new
 style 10.5 built-in migration tools. I'd abandoned my ad-hoc Tiger one
 a while back and finally needed to migrate.
 
 I'm building on Snow Leopard, and bugs and glitches aside (such as the
 workaround for migration for Leopard deployment built on Snow
 Leopard), it's mostly working. But what it boils down to is when I
 deploy it on Leopard, the migration is correctly performed, but then
 the app insists upon re-opening the foo~.ext file (the backup with the
 tilde) instead of the actual upgraded data file itself. The simple
 solution is just to shut the doc w/o saving, then re-open it. All
 problems solved when I do that, but I don't really want to ask my
 users to do it.
 
 It behaves just fine on Snow Leopard.
 
 I found some old posts referencing the issue, such as:
 http://lists.apple.com/archives/cocoa-dev/2009/Nov/msg01431.html
 
 But no functional solutions. I tried implementing mmalc's custom
 NSDocumentController subclass, but the issue persisted. So I dropped
 it out and left just the standard modification to
 configurePersistentStoreCoordinatorForURL: to turn on
 forKey:NSMigratePersistentStoresAutomaticallyOption.
 
 Sometimes the ~ pops up in the title bar, sometimes it doesn't. The
 doc is never actually save-able.
 
 Did anyone ever discover a viable solution?
 
 -Jim
 ___
 
 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/mlink%40fractal.net
 
 This email sent to ml...@fractal.net
 
 

___

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


Core Data Migration Error

2011-01-16 Thread Michael Link
I keep getting this error when trying to migrate a sql store:

-[Document 
configurePersistentStoreCoordinatorForURL:ofType:modelConfiguration:storeOptions:error:]
 Error NSCocoaErrorDomain 134110 {
NSUnderlyingException = I/O error for database at 
/Users/mlink/Desktop/Untitled.db.new.  SQLite error code:1, 'no such table: 
_T_ZEVENT';
destinationURL = file://localhost/Users/mlink/Desktop/Untitled.db.new;
reason = Cannot migrate store in-place;
sourceURL = file://localhost/Users/mlink/Desktop/Untitled.db;
}

This migration is using the default mapping model created in Xcode. The Event 
entity was changed to have an abstract parent entity, before it stood alone.

I tried creating an entity migration policy subclass but none of its methods 
are called. Anyone have any ideas what the problem might be?

--
Michael___

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


NSHTTPCookieStorage

2010-11-11 Thread Michael Link
Did something recently change with sharedHTTPCookieStorage no longer sharing 
session cookies?

--
Michael___

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


NSPersistentDocument and canConcurrentlyReadDocumentsOfType

2010-10-12 Thread Michael Link
In the documentation for NSPersistentDocument's method -managedObjectModel it 
says the following addition in a subclass can be used to improve efficiency if 
all the documents share the same model.

 - (id)managedObjectModel {
 static id sharedModel = nil;
 if (sharedModel == nil) {
 sharedModel = [[super managedObjectModel] retain];
 }
 return sharedModel;
 }

If the app is running on 10.6 and returns YES for 
canConcurrentlyReadDocumentsOfType I'm assuming some sort of synchronization 
would be necessary here?

--
Michael___

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


non-pointer instance variable

2010-07-15 Thread Michael Link
Is it necessary to use objc_atomicCompareAndSwapInstanceVariableBarrier when 
setting an instance variable such as an NSInteger in a GC app? Or would 
OSAtomicCompareAndSwap64Barrier be more appropriate?

--
Michael___

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


atomic properties and KVC

2010-07-14 Thread Michael Link
If I have a property declared and synthesized (e.g.
@property BOOL foo;

and I use a KVC method to access the value of foo (e.g.
[object valueForKey:@foo];

is it still accessed atomically? 

--
Michael
___

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


first responder being clobbered

2009-10-26 Thread Michael Link
I have a custom UITableViewController that uses a custom cell that  
displays a text field. I have this method added to the table view  
controller to set the text field as first responder


- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];

	MLPropertyEditingTableViewCell* __cell =  
(MLPropertyEditingTableViewCell*)[self.tableView cellForRowAtIndexPath: 
[NSIndexPath indexPathForRow:0 inSection:0]];


[__cell.textField becomeFirstResponder];
}

This works on iPhone OS 3.0, but not on iPhone OS 3.1. It appears that  
on 3.1 there is an observer that calls reloadData on the table view  
and that forces the first responder to resign.


#0	0x7b9d in -[FRProjectNamePropertyEditorViewController  
textFieldDidEndEditing:] at  
FRProjectNamePropertyEditorViewController.m:131

#1  0x0030b1ea in -[UITextField fieldEditorDidResignFirstResponder:]
#2  0x00319b61 in -[UIFieldEditor resignFirstResponder]
#3  0x0030d341 in -[UITextField resignFirstResponder]
#4  0x002f4384 in -[UITableView reloadData]
#5  0x002f189f in -[UITableView layoutSubviews]
#6  0x036c62b0 in -[CALayer layoutSublayers]
#7  0x036c606f in CALayerLayoutIfNeeded
#8  0x036c58c6 in CA::Context::commit_transaction
#9  0x036c553a in CA::Transaction::commit
#10 0x036cd838 in CA::Transaction::observer_callback
#11 0x01d49252 in __CFRunLoopDoObservers
#12 0x01d4865f in CFRunLoopRunSpecific
#13 0x01d47c48 in CFRunLoopRunInMode
#14 0x0253478d in GSEventRunModal
#15 0x02534852 in GSEventRun
#16 0x002ab003 in UIApplicationMain
#17 0x2980 in main at main.m:14

Is there a different solution to getting a first responder in a table  
cell and not having it resign on 3.1?


--
Michael
___

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: Mac OS X 10.5.8 update breaks tokenize function in -[NSXMLNode objectsForXQuery:error:]

2009-08-06 Thread Michael Link
After some more investigation I've discovered that XQuery was updated  
in Mac OS X 10.5.8 as part of a security vulnerability in the PCRE  
library which it includes.


http://support.apple.com/kb/HT3757 (scroll to bottom of page)

Which also explains why all XQuery functions using regular expressions  
are also broken. Digging into the PCRE portion of the XQuery code  
reveals the following PCRE error string after trying to compile a  
regular expression:


this version of PCRE is not compiled with PCRE_UTF8 support

#0  0x0010f430 in pcre_compile
#1  0x00100495 in -[XQueryRegEx initExpr:withFlags:]
#2  0x000ff944 in +[XQueryRegEx regExp:withFlags:]
#3  0x000ce8e3 in fn_tokenize
#4  0x000db9cd in -[XQueryFunctionCall evaluateWithContext:]
#5  0x000f62b5 in -[XQueryExprList evaluateWithContext:]
#6	0x00102a9a in -[XQueryContext  
evaluateXQuery:constants:contextItem:error:]

#7  0x92201d98 in -[NSXMLNode objectsForXQuery:constants:error:]
#8  0x92303338 in -[NSXMLNode objectsForXQuery:error:]
#9  0x1d04 in -[Bug7037807 performXQuery:] at Bug7037807.m:40
#10 0x1c15 in -[Bug7037807 awakeFromNib] at Bug7037807.m:27
#11 0x9310f7f5 in -[NSSet makeObjectsPerformSelector:]
#12	0x910d2d8e in -[NSIBObjectData  
nibInstantiateWithOwner:topLevelObjects:]

#13 0x910c8fba in loadNib
#14	0x910c891c in +[NSBundle(NSNibLoading)  
_loadNibFile:nameTable:withZone:ownerBundle:]
#15	0x910c855f in +[NSBundle(NSNibLoading)  
loadNibFile:externalNameTable:withZone:]

#16 0x910c849d in +[NSBundle(NSNibLoading) loadNibNamed:owner:]
#17 0x910c814c in NSApplicationMain
#18 0x1ae8 in main at main.m:13

Dump of assembler code for function pcre_compile:
0x0010f3fb pcre_compile+0:  push   %ebp
0x0010f3fc pcre_compile+1:  mov%esp,%ebp
0x0010f3fe pcre_compile+3:  sub$0x28,%esp
0x0010f401 pcre_compile+6:  mov0x18(%ebp),%eax
0x0010f404 pcre_compile+9:  movl   $0x0,0x8(%esp)
0x0010f40c pcre_compile+17: mov%eax,0x14(%esp)
0x0010f410 pcre_compile+21: mov0x14(%ebp),%eax
0x0010f413 pcre_compile+24: mov%eax,0x10(%esp)
0x0010f417 pcre_compile+28: mov0x10(%ebp),%eax
0x0010f41a pcre_compile+31: mov%eax,0xc(%esp)
0x0010f41e pcre_compile+35: mov0xc(%ebp),%eax
0x0010f421 pcre_compile+38: mov%eax,0x4(%esp)
0x0010f425 pcre_compile+42: mov0x8(%ebp),%eax
0x0010f428 pcre_compile+45: mov%eax,(%esp)
0x0010f42b pcre_compile+48: call   0x10eb91 pcre_compile2
0x0010f430 pcre_compile+53: leave
0x0010f431 pcre_compile+54: ret
End of assembler dump.
(gdb) x/i $eip
0x10f430 pcre_compile+53:   leave

(gdb) p *(int*)($ebp + 16)
$26 = -1073745996
(gdb) p *$26
$27 = 1254561
(gdb) x/s $27
0x1324a1 error_texts+1033:	 this version of PCRE is not compiled  
with PCRE_UTF8 support


Did someone forget to turn on a compile flag?

--
Michael
___

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


embedding framework in Application bundle?

2009-08-06 Thread Michael Link
I'm trying to work around a problem where the latest update of Mac OS  
X (10.5.8) has a broken XQuery.framework. I've discovered that  
replacing the XQuery.framework on Mac OS X 10.5.8 with a version from  
Mac OS X 10.5.7 solves all the problems.


I'd like to embed the XQuery.framework from Mac OS X 10.5.7 in my  
application and force it to be used over the faulty system version on  
Mac OS X 10.5.8. I've managed to get it into the application bundle  
and setting the environment variables DYLD_PRINT_LIBRARIES and  
DYLD_PRINT_LIBRARIES_POST_LAUNCH show that it's being loaded but it  
doesn't appear that the framework is being used. GDB also shows that  
the symbols are loaded, I can create breakpoints on functions in the  
XQuery.framework. I'm wondering why when I call -[NSXMLNode  
objectsForXQuery:error:] it doesn't call out to the corresponding  
functions in the XQuery.framework unless it's been loaded from /System/ 
Library/PrivateFrameworks?


dyld: loaded: /Users/mlink/Code/code-cocoaref/Bug7037807/build/Debug/ 
Bug7037807.app/Contents/MacOS/Bug7037807
dyld: loaded: /Developer/Applications/Xcode.app/Contents/Resources/../ 
PlugIns/GDBMIDebugging.xcplugin/Contents/Resources/ 
PBGDBIntrospectionSupport.A.dylib
dyld: loaded: /System/Library/Frameworks/Cocoa.framework/Versions/A/ 
Cocoa
dyld: loaded: /Users/mlink/Code/code-cocoaref/Bug7037807/build/Debug/ 
Bug7037807.app/Contents/MacOS/../Frameworks/XQuery.framework/Versions/ 
A/XQuery

dyld: loaded: /usr/lib/libgcc_s.1.dylib
...

(gdb) info break
Num Type   Disp Enb AddressWhat
1   breakpoint keep y   0x00116df6 pcre_compile+6
2   breakpoint keep y   0x00116587 pcre_compile2+6
3   breakpoint keep y   0x0010efab pcre_exec+9
4   breakpoint keep y   0x000dee6e -[XQueryFunctionCall  
evaluateWithContext:]+6

(gdb) info sym 0x00116df6
pcre_compile + 6 in section LC_SEGMENT.__TEXT.__text of /Users/mlink/ 
Code/code-cocoaref/Bug7037807/build/Debug/Bug7037807.app/Contents/ 
Frameworks/XQuery.framework/Versions/A/XQuery

(gdb) info sym 0x000dee6e
-[XQueryFunctionCall evaluateWithContext:] + 6 in section  
LC_SEGMENT.__TEXT.__text of /Users/mlink/Code/code-cocoaref/Bug7037807/ 
build/Debug/Bug7037807.app/Contents/Frameworks/XQuery.framework/ 
Versions/A/XQuery


Anyone know how I might be able to get this to work?

--
Michael
___

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


Mac OS X 10.5.8 update breaks tokenize function in -[NSXMLNode objectsForXQuery:error:]

2009-08-05 Thread Michael Link
I noticed that the recent update of Mac OS X 10.5.8 breaks  
compatibility with previous versions regarding XQuery statements in  
NSXMLNode, specifically using the XQuery function tokenize. I  
originally reported this bug against a future version of Mac OS X and  
now seems to have slipped into the latest update of Mac OS X 10.5.


rdar://problem/7037807

The following code works on Mac OS X 10.5.0 - 10.5.7 but does not work  
on Mac OS X 10.5.8.


@interface Bug7037807 : NSObject
{
NSXMLDocument* _document;
}
- (void)performXQuery:(NSString*)query;
@end

@implementation Bug7037807

- (id)init
{
if (self = [super init]) {
		_document = [[NSXMLDocument alloc]  
initWithXMLString:@htmltitletitle/titlebodyh1header/ 
h1pastring, bstring, cstring, dstring, estring/ppastring   
bstring  cstring  dstring  estring/p/body/html  
options:NSXMLDocumentTidyHTML error:nil];

}

return self;
}

- (void)awakeFromNib
{
[self performXQuery:@/descendant-or-self::p[1]];
[self performXQuery:@xs:string(/descendant-or-self::p[1])];
	[self performXQuery:@tokenize(xs:string(/descendant-or-self::p[1]),  
',')];

}

- (void)performXQuery:(NSString*)query
{
NSError* __error = nil;
NSArray* __results;

__results = [_document objectsForXQuery:query error:__error];

if (!__results) {
NSLog(@error: %@, __error);
}
else {
NSLog(@results: %@, __results);
}
}

@end


Output on Mac OS X 10.5.0 - 10.5.7

2009-08-05 23:34:49.428 Bug7037807[577:10b] results: (
pastring, bstring, cstring, dstring, estring
/p
)
2009-08-05 23:34:49.431 Bug7037807[577:10b] results: (
astring, bstring, cstring, dstring, estring\n
)
2009-08-05 23:34:49.432 Bug7037807[577:10b] results: (
astring,
 bstring,
 cstring,
 dstring,
 estring\n
)



Output on Mac OS X 10.5.8

2009-08-05 23:34:49.428 Bug7037807[577:10b] results: (
pastring, bstring, cstring, dstring, estring
/p
)
2009-08-05 23:34:49.431 Bug7037807[577:10b] results: (
astring, bstring, cstring, dstring, estring\n
)
2009-08-05 23:34:49.432 Bug7037807[577:10b] error: XQueryError:17 -  
invalid arguments to function - tokenize


What does the 10.5.8 version of tokenize want as arguments? Any known  
work-around?


--
Michael

___

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 pointer to object

2009-05-21 Thread Michael Link

I have a class with the following methods

- (void)save
{
NSError* error = nil;

if (![self save:error]) {
NSLog(@caught error during save: %@, error);
}
}

- (BOOL)save:(NSError**)error
{
if (![_thread isCancelled]) {
return [_managedObjectContext save:error];
}

return YES;
}

When -save is called it calls -save: to get error information if an  
error occurs while saving an NSManagedObjectContext. When an error  
does occur sometimes a crash will occur at NSLog when trying to get  
the NSError description. Is it possible that the local variable error  
in -save is being garbage collected before NSLog is called?


Thread 0 Crashed:
0   com.apple.CoreFoundation  	0x7fff833bd24a  
CFBundleCopyLocalizedString + 90
1   com.apple.CoreFoundation  	0x7fff833db111  
_CFErrorCreateLocalizedDescription + 273
2   com.apple.Foundation  	0x7fff81f0f3f8 -[NSError  
localizedDescription] + 136
3   com.apple.CoreFoundation  	0x7fff833db25a  
CFErrorCopyDescription + 138
4   com.apple.CoreFoundation  	0x7fff833db2b4  
_CFErrorCreateDebugDescription + 36
5   com.apple.Foundation  	0x7fff81f0f349 -[NSError  
description] + 9
6   com.apple.Foundation  	0x7fff81e83770  
_NSDescriptionWithLocaleFunc + 128
7   com.apple.CoreFoundation  	0x7fff83428b54  
_CFStringAppendFormatAndArgumentsAux + 2964
8   com.apple.CoreFoundation  	0x7fff83429fa8  
_CFStringCreateWithFormatAndArgumentsAux + 120

9   com.apple.CoreFoundation0x7fff8345dab0 _CFLogvEx + 64
10  com.apple.Foundation0x7fff81e9ba0b NSLogv + 139
11  com.apple.Foundation0x7fff81ef69a2 NSLog + 162
12  net.fractal.Bug	0x000100094d74 0x1 +  
609652
13  net.fractal.Bug	0x000100050e58 0x1 +  
331352
14  com.apple.CoreFoundation  	0x7fff8347dead __invoking___ +  
141
15  com.apple.CoreFoundation  	0x7fff8347d774 -[NSInvocation  
invoke] + 148
16  net.fractal.Bug	0x000100040b6d 0x1 +  
265069
17  com.apple.CoreFoundation  	0x7fff8347dead __invoking___ +  
141
18  com.apple.CoreFoundation  	0x7fff8347d774 -[NSInvocation  
invoke] + 148
19  com.apple.CoreFoundation  	0x7fff8347d833 -[NSInvocation  
invokeWithTarget:] + 51
20  com.apple.Foundation  	0x7fff81e7f754  
__NSThreadPerformPerform + 148
21  com.apple.CoreFoundation  	0x7fff83404008  
CFRunLoopRunSpecific + 2808
22  com.apple.HIToolbox   	0x7fff82a71bce  
RunCurrentEventLoopInMode + 278
23  com.apple.HIToolbox   	0x7fff82a71963  
ReceiveNextEventCommon + 161
24  com.apple.HIToolbox   	0x7fff82a718af  
BlockUntilNextEventMatchingListInMode + 79
25  com.apple.AppKit  	0x7fff80a89420 _DPSNextEvent +  
603
26  com.apple.AppKit  	0x7fff80a88d61 -[NSApplication  
nextEventMatchingMask:untilDate:inMode:dequeue:] + 136
27  com.apple.AppKit  	0x7fff80d07457 -[NSScrollView  
scrollWheel:] + 721
28  com.apple.AppKit  	0x7fff80be9d59 forwardMethod +  
100
29  com.apple.AppKit  	0x7fff80d0716e -[NSView  
scrollWheel:] + 249
30  com.apple.AppKit  	0x7fff80be9d59 forwardMethod +  
100
31  com.apple.AppKit  	0x7fff80d0716e -[NSView  
scrollWheel:] + 249
32  com.apple.AppKit  	0x7fff80b5b40b -[NSWindow  
sendEvent:] + 6820
33  com.apple.AppKit  	0x7fff80b282f6 -[NSApplication  
sendEvent:] + 5089
34  com.apple.AppKit  	0x7fff80a82b20 -[NSApplication  
run] + 499
35  com.apple.AppKit  	0x7fff80a4f8ac  
NSApplicationMain + 373
36  net.fractal.Bug	0x000196fb 0x1 +  
38651
37  net.fractal.Bug	0x000121b8 0x1 +  
8632


Thread 1:
0   libauto.dylib  	0x0001006876e4  
Auto::Admin::deallocate(void*) + 772
1   libauto.dylib  	0x00010068e623  
Auto::Zone::block_deallocate_internal(void*) + 355
2   libauto.dylib  	0x00010067c1cd  
auto_collect_internal(Auto::Zone*, unsigned int) + 2685
3   libauto.dylib  	0x00010067c380  
auto_collection_thread(void*) + 112
4   libSystem.B.dylib 	0x7fff827ade8b _pthread_start +  
316

5   libSystem.B.dylib   0x7fff827add4d thread_start + 13


--
Michael
___

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 garbage collection race condition?

2009-01-14 Thread Michael Link
I'm running into a scenario where it appears the application is  
allocating memory faster than it can be reclaimed by garbage  
collection. I believe this is how it happens.


There are a pool of threads that are used to collect some data as it  
is collected (by using NSXML* objects, XQuery). In the beginning the  
generational collections seem to keep up well since almost all of the  
NSXML* objects become garbage very quickly. After a small bit of time  
though no garbage collection takes place and memory is consumed to the  
point of exhaustion. (I have AUTO_LOG_COLLECTIONS=YES set to see when  
collections take place).


Some analysis during the period that no collections are taking place  
actually reveals that the collector thread is at this point:


#0  0x001d3a37 in Auto::Bitmap::bit at AutoBitmap.h:131
#1  0x001dca84 in Auto::Region::is_pending at AutoRegion.h:209
#2  0x001db587 in Auto::Admin::is_pending at AutoAdmin.cpp:415
#3  0x001ee3cd in Auto::Subzone::is_pending at AutoSubzone.h:472
#4	0x001eec1e in Auto::scan_pending_blocks_visitor::visit at  
AutoMemoryScanner.cpp:631


#5	0x001eed55 in  
Auto::visitAllocatedBlocksAuto::scan_pending_blocks_visitor at  
AutoBlockIterator.h:53
#6	0x001eddb4 in Auto::MemoryScanner::scan_pending_blocks at  
AutoMemoryScanner.cpp:658
#7	0x001ede0e in Auto::MemoryScanner::scan_pending_until_done at  
AutoMemoryScanner.cpp:680

#8  0x001edfb5 in Auto::MemoryScanner::scan at AutoMemoryScanner.cpp:731
#9  0x001e8c31 in Auto::Collector::collect at AutoCollector.cpp:64
#10 0x001e0f89 in Auto::Zone::collect at AutoZone.cpp:1324
#11 0x001d20c7 in auto_collect_internal at auto_zone.cpp:258
#12 0x001d282c in auto_collect_with_mode at auto_zone.cpp:375
#13 0x001d28c2 in auto_collection_thread at auto_zone.cpp:397
#14 0x91dc3095 in _pthread_start
#15 0x91dc2f52 in thread_start

Whenever I break into gdb to see where it's at during this point  
Auto::visitAllocatedBlocksAuto::scan_pending_blocks_visitor has  
always been in the stack trace. My guess would be that pending  
blocks are being added faster than they are scanned...


To get around this problem I've tried making each thread call

objc_collect(OBJC_EXHAUSTIVE_COLLECTION|OBJC_WAIT_UNTIL_DONE);

after it's done with its task, but it doesn't actually seem to wait at  
all. Since there already seems to be a collection taking place the  
call returns and the thread continues.


Is there anyway to truly block execution until collection has  
finished? Are there any callbacks that could notify when collection  
has started and ended?


I wouldn't mind moving the temporary objects allocation to an  
unscanned zone, but there doesn't seem to be an equivalent  
CoreFoundation way to use XQuery as there is in NSXMLNode.


--
Michael
___

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


agc error for object ... Deallocating a non-block

2008-12-31 Thread Michael Link

When I see an error on the console that looks like this:

Test(22389,0xb0103000) malloc: *** free() called with 0x1f29ba00 with  
refcount 0
Test(22389,0xb0103000) malloc: *** auto malloc[22389]: agc error for  
object 0x1f29ba00: Deallocating a non-block


What exactly does 'Deallocating a non-block' mean?

I was running with malloc history on and the last 2 stack traces for  
0x1f29ba00 are:


Stack - pthread: 0xa0580720 number of frames: 28
0: 0x951e482d in malloc_zone_calloc
1: 0x951e4782 in calloc
2: 0x902158cc in CGImageSourceGetTypeWithData
3: 0x90215712 in CGImageSourceGetTypeWithData
4: 0x901e61be in CGImageSourceCreateImageAtIndex
5: 0x901ebb1c in CGImageSourceGetPropertiesAtIndex
6: 0x901eba76 in CGImageSourceCopyPropertiesAtIndex
7: 0x91e6be8b in +[NSBitmapImageRep  
_imagesWithData:hfsFileType:extension:zone:expandImageContentNow:includeAllReps 
:]

8: 0x91e6fc71 in +[NSBitmapImageRep imageRepsWithData:]
9: 0x91e6f50e in -[NSImage initWithData:]
   10: 0x7375d in -[SPCaptchaImageView connectionDidFinishLoading:]  
at /Users/mlink/Code/code-cocoa/Test/trunk/Test/SPCaptchaImageView.m:259

   11: 0x95739a3d in __invoking___
   12: 0x95739428 in -[NSInvocation invoke]
   13: 0xf0a0b in -[MLHTTPConnection _didFinishLoading] at /Users/ 
mlink/Code/code-cocoa/Test/trunk/Test/MLHTTPConnection.m:204

   14: 0x95739a3d in __invoking___
   15: 0x95739428 in -[NSInvocation invoke]
   16: 0x94f3039c in __NSThreadPerformPerform
   17: 0x956ba5f5 in CFRunLoopRunSpecific
   18: 0x956bacd8 in CFRunLoopRunInMode
   19: 0x927392c0 in RunCurrentEventLoopInMode
   20: 0x927390d9 in ReceiveNextEventCommon
   21: 0x92738f4d in BlockUntilNextEventMatchingListInMode
   22: 0x91d80d7d in _DPSNextEvent
   23: 0x91d80630 in -[NSApplication  
nextEventMatchingMask:untilDate:inMode:dequeue:]

   24: 0x91d7966b in -[NSApplication run]
   25: 0x91d468a4 in NSApplicationMain
   26: 0xc884 in main at /Users/mlink/Code/code-cocoa/Test/trunk/Test/ 
main.m:25

   27: 0x2e52 in start
Stack - pthread: 0xa0580720 number of frames: 28
0: 0x951e2323 in malloc_zone_free
1: 0x951e22cd in free
2: 0x90256516 in CGImagePluginSetClipPath
3: 0x949f43c8 in CGDataProviderCreateWithFaultDataCallback
4: 0x94809f17 in CGDataProviderGetBytePtr
5: 0x901e9e70 in CGImagePluginSetBandProc
6: 0x91e6e168 in -[NSBitmapImageRep _loadData]
7: 0x91e6bf27 in +[NSBitmapImageRep  
_imagesWithData:hfsFileType:extension:zone:expandImageContentNow:includeAllReps 
:]

8: 0x91e6fc71 in +[NSBitmapImageRep imageRepsWithData:]
9: 0x91e6f50e in -[NSImage initWithData:]
   10: 0x7375d in -[SPCaptchaImageView connectionDidFinishLoading:]  
at /Users/mlink/Code/code-cocoa/Test/trunk/Test/SPCaptchaImageView.m:259

   11: 0x95739a3d in __invoking___
   12: 0x95739428 in -[NSInvocation invoke]
   13: 0xf0a0b in -[MLHTTPConnection _didFinishLoading] at /Users/ 
mlink/Code/code-cocoa/Test/trunk/Test/MLHTTPConnection.m:204

   14: 0x95739a3d in __invoking___
   15: 0x95739428 in -[NSInvocation invoke]
   16: 0x94f3039c in __NSThreadPerformPerform
   17: 0x956ba5f5 in CFRunLoopRunSpecific
   18: 0x956bacd8 in CFRunLoopRunInMode
   19: 0x927392c0 in RunCurrentEventLoopInMode
   20: 0x927390d9 in ReceiveNextEventCommon
   21: 0x92738f4d in BlockUntilNextEventMatchingListInMode
   22: 0x91d80d7d in _DPSNextEvent
   23: 0x91d80630 in -[NSApplication  
nextEventMatchingMask:untilDate:inMode:dequeue:]

   24: 0x91d7966b in -[NSApplication run]
   25: 0x91d468a4 in NSApplicationMain
   26: 0xc884 in main at /Users/mlink/Code/code-cocoa/Test/trunk/Test/ 
main.m:25

   27: 0x2e52 in start

--
Michael
___

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


copy object in kCFAllocatorMallocZone to scanned zone?

2008-12-23 Thread Michael Link

I have a situation with something like this is going on:

CFHTTPMessageRef response =  
CFHTTPMessageCreateEmpty(kCFAllocatorMallocZone, FALSE);


CFHTTPMessageAppendBytes(response, bytes, length);

if (CFHTTPMessageIsHeaderComplete(response)) {
CFIndex statusCode = CFHTTPMessageGetResponseStatusCode(response);
	NSDictionary* headerFields =  
(NSDictionary*)CFHTTPMessageCopyAllHeaderFields(response);

}

Which is taking place in a garbage collected environment. Would the  
headerFields variable use the same allocator used to create the  
response (kCFAllocatorMallocZone) or would it be using the default  
allocator which would mean that it would be in scanned memory?


If headerFields is allocated with kCFAllocatorMallocZone, and I copy  
like this:


NSDictionary* headerFieldsCopy = [headerFields copy];

Would the copy be allocated with kCFAllocatorMallocZone or the default  
allocator?


I would like to copy headerFields to scanned memory because it could  
be passed as the argument to something that assumes it is in scanned  
memory.


--
Michael
___

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: copy object in kCFAllocatorMallocZone to scanned zone?

2008-12-23 Thread Michael Link


On Dec 23, 2008, at 1:19 PM, Michael Link wrote:


I have a situation with something like this is going on:

CFHTTPMessageRef response =  
CFHTTPMessageCreateEmpty(kCFAllocatorMallocZone, FALSE);


CFHTTPMessageAppendBytes(response, bytes, length);

if (CFHTTPMessageIsHeaderComplete(response)) {
CFIndex statusCode = CFHTTPMessageGetResponseStatusCode(response);
	NSDictionary* headerFields =  
(NSDictionary*)CFHTTPMessageCopyAllHeaderFields(response);

}

Which is taking place in a garbage collected environment. Would the  
headerFields variable use the same allocator used to create the  
response (kCFAllocatorMallocZone) or would it be using the default  
allocator which would mean that it would be in scanned memory?


If headerFields is allocated with kCFAllocatorMallocZone, and I copy  
like this:


NSDictionary* headerFieldsCopy = [headerFields copy];

Would the copy be allocated with kCFAllocatorMallocZone or the  
default allocator?


I would like to copy headerFields to scanned memory because it could  
be passed as the argument to something that assumes it is in scanned  
memory.


Would this be the correct way to copy the dictionary from the malloc  
zone to the scanned zone?


NSDictionary* headerFieldsCopy =  
(NSDictionary*)CFDictionaryCreateCopy(NULL,  
(CFDictionaryRef)headerFields);


--
Michael

___

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 memory leak

2008-12-17 Thread Michael Link
I'm trying to track down a memory leak even though I'm using garbage  
collection. I was curious what the rc: field means when using info  
gc-roots in gdb? It doesn't seem to correlate to the Retain Count  
when inspecting an address in Instruments and it doesn't seem to  
always correlate to using info gc-references in gdb. I would tend to  
assume that it would make more sense if it meant the retain count  
since that would explain why the root objects have something  0.


After running about 40 NSURLConnections in an application and closing  
out everything so that only the menu bar is left I noticed that there  
are some objects not being collected that are definitely not being  
used anymore and should have been collected.


Some of the objects I noticed right away are NSXMLDocuments which are  
created right after a connection sends the - 
connectionDidFinishLoading: delegate message. The method looks like:


- (void)connectionDidFinishLoading:(NSURLConnection*)connection
{
NSError* error = nil;
	NSString* string = [[NSString alloc] initWithData:connection.data  
encoding:NSUTF8StringEncoding];

NSXMLDocument* document = nil;

	if (document = [[NSXMLDocument alloc] initWithXMLString:string  
options:[self options] error:error]) {
		... extract some NSStrings using objectsForXQuery:@xs:string(/ 
some[1]/path[1])

... assign strings to NSManagedObject
}
}

the -connectionDidFinishLoading: runs on a background thread that is  
using NSRunLoop, so the stack should be cleared.


The root objects for 1 of these NSXMLDocuments is:

(gdb) info gc-roots 0x17815b0
Number of roots: 3
Root:
warning: can't find class named `NSCFType' given by ObjC class object
   0 Kind: object  rc:   2  Address: 0x014bab40  Offset: 0x0044   
Class: NSCFType

warning: can't find class named `a' given by ObjC class object
   1 Kind: object  rc:   0  Address: 0x014b2070  Offset: 0x0020   
Class: NSCFType

   2 Kind: bytes   rc:   0  Address: 0x014af730  Offset: 0x0018
warning: can't find class named `NSXMLNamedNode' given by ObjC class  
object
   3 Kind: object  rc:   0  Address: 0x0148fb10  Offset: 0x0008   
Class: NSXMLNamedNode
   4 Kind: object  rc:   0  Address: 0x0148fae0  Class: NSXMLElement   
ivar: NSXMLNode._parent
   5 Kind: object  rc:   0  Address: 0x0148fab0  Class: NSXMLElement   
ivar: NSXMLNode._parent
   6 Kind: object  rc:   0  Address: 0x01493010  Class: NSXMLElement   
ivar: NSXMLNode._parent
   7 Kind: object  rc:   0  Address: 0x01492fe0  Class: NSXMLElement   
ivar: NSXMLNode._parent
   8 Kind: object  rc:   0  Address: 0x014942a0  Class: NSXMLElement   
ivar: NSXMLNode._parent
   9 Kind: object  rc:   0  Address: 0x014970e0  Class: NSXMLElement   
ivar: NSXMLNode._parent
  10 Kind: object  rc:   0  Address: 0x01498570  Class: NSXMLElement   
ivar: NSXMLNode._parent
  11 Kind: object  rc:   0  Address: 0x014a5280  Class: NSXMLElement   
ivar: NSXMLNode._parent
  12 Kind: object  rc:   0  Address: 0x014b1710  Class: NSXMLElement   
ivar: NSXMLNode._parent
  13 Kind: object  rc:   0  Address: 0x016a0c50  Class: NSXMLElement   
ivar: NSXMLNode._parent
  14 Kind: object  rc:   0  Address: 0x016c6a80  Class: NSXMLElement   
ivar: NSXMLNode._parent
  15 Kind: object  rc:   0  Address: 0x016c6980  Class: NSXMLElement   
ivar: NSXMLNode._parent
  16 Kind: object  rc:   0  Address: 0x016c68a0  Class: NSXMLElement   
ivar: NSXMLNode._parent
  17 Kind: object  rc:   0  Address: 0x01730560  Class: NSXMLElement   
ivar: NSXMLNode._parent
  18 Kind: object  rc:   0  Address: 0x01735060  Class: NSXMLElement   
ivar: NSXMLNode._parent
  19 Kind: object  rc:   0  Address: 0x01d66d50  Class: NSXMLElement   
ivar: NSXMLNode._parent
  20 Kind: object  rc:   0  Address: 0x020948e0  Class: NSXMLElement   
ivar: NSXMLNode._parent

  21 Kind: object  rc:   0  Address: 0x017815b0  Class: NSXMLDocument
Root:
warning: can't find class named `a' given by ObjC class object
   0 Kind: object  rc:   1  Address: 0x014badb0  Offset: 0x0014   
Class: NSCFType

warning: can't find class named `a' given by ObjC class object
   1 Kind: object  rc:   2  Address: 0x014bab40  Offset: 0x0044   
Class: NSCFType

warning: can't find class named `a' given by ObjC class object
   2 Kind: object  rc:   0  Address: 0x014b2070  Offset: 0x0020   
Class: NSCFType

   3 Kind: bytes   rc:   0  Address: 0x014af730  Offset: 0x0018
warning: can't find class named `a' given by ObjC class object
   4 Kind: object  rc:   0  Address: 0x0148fb10  Offset: 0x0008   
Class: NSXMLNamedNode
   5 Kind: object  rc:   0  Address: 0x0148fae0  Class: NSXMLElement   
ivar: NSXMLNode._parent
   6 Kind: object  rc:   0  Address: 0x0148fab0  Class: NSXMLElement   
ivar: NSXMLNode._parent
   7 Kind: object  rc:   0  Address: 0x01493010  Class: NSXMLElement   
ivar: NSXMLNode._parent
   8 Kind: object  rc:   0  Address: 0x01492fe0  Class: NSXMLElement   
ivar: NSXMLNode._parent
   9 Kind: object  rc:   0  

GC and propertyListFromData:mutabilityOption:format:errorDescription:

2008-11-10 Thread Michael Link
The documentation for  
propertyListFromData:mutabilityOption:format:errorDescription: says  
that errorDescription needs to be released by the caller. In a garbage  
collected environment is this still the case? Should  
NSMakeCollectable() be called on errorDescription?


Is it safe to call NSMakeCollectable() multiple times on the same  
object (when in doubt)?


--
Michael
___

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 [EMAIL PROTECTED]


Re: -[NSGarbageCollection disableCollectorForPointer:] ?

2008-10-15 Thread Michael Link
That makes sense, although 'NSPointerFunctionsStrongMemory| 
NSPointerFunctionsOpaqueMemory' gives the error:


*** -[NSPointerArray initWithOptions:] Requested configuration not  
supported.


What I did try was 'NSPointerFunctionsStrongMemory| 
NSPointerFunctionsObjectPointerPersonality' which does work even  
though some of the pointers aren't objects and this doesn't seem quite  
correct but since I'm using GC  
NSPointerFunctionsObjectPointerPersonality seems nearly equivalent to  
NSPointerFunctionsOpaquePersonality as long as description isn't called.


--
Michael

On Oct 15, 2008, at 1:08 AM, Ken Ferry wrote:


Hi Michael,

NSPointerFunctionsStrongMemory|NSPointerFunctionsOpaqueMemory doesn't
make sense. You're meant to specify only one of the memory options and
only one of the personality options.

Due to the way the bitfield work, your invocation is the same as
NSPointerFunctionsOpaqueMemory|NSPointerFunctionsOpaquePersonality.
This is the mode in which the pointer array is completely hands-off.
It acts like a C array.

Try NSPointerFunctionsStrongMemory| 
NSPointerFunctionsOpaquePersonality.

That sounds right to me, though I get confused with the pointer
functions too.

-Ken

On Tue, Oct 14, 2008 at 9:43 PM, Michael Link [EMAIL PROTECTED]  
wrote:

I have a situation where I create an NSPointerArray on the stack by:

pointers = [NSPointerArray
pointerArrayWithOptions:NSPointerFunctionsStrongMemory| 
NSPointerFunctionsOpaqueMemory|NSPointerFunctionsOpaquePersonality];


I then go about adding a few objects a selector and a pointer  
(contextInfo

that could point to anything even a non-object) to the pointer array.

I then call:

[[NSGarbageCollector defaultCollector]  
disableCollectorForPointer:pointers];


The pointer array is then passed as the contextInfo for another  
method
(which turns out to be a weak reference), but isn't garbage  
collected due to
the previous call. The interesting part turns out that the object  
at index 0
(NSError* in this case) in the pointer array is garbage collected  
(probably
because it was a variable in the function that called us). The  
pointer array
is configured to use strong references therefore index 0 isn't set  
to NULL
and something else is located at that memory (sometimes a different  
object,

sometimes garbage memory).

If I use:

[[NSGarbageCollector defaultCollector] disableCollectorForPointer: 
[pointers

pointerAtIndex:0]];

nothing bad happens and that object isn't collected.

According to the documentation for disableCollectorForPointer:  
shouldn't the
pointer array be considered a new root object, and none of it's  
pointers

collected? Especially since it uses strong references?

--
Michael
___

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/kenferry%40gmail.com

This email sent to [EMAIL PROTECTED]






___

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 [EMAIL PROTECTED]


Re: -[NSGarbageCollection disableCollectorForPointer:] ?

2008-10-15 Thread Michael Link
I actually went with using NSAllocateCollectable(NSScannedOption) and  
that seems to be working well. Thanks.


--
Michael

On Oct 15, 2008, at 9:21 PM, Ken Ferry wrote:

Or you could malloc the memory for the buffer (free'ing it when  
you're done) and disable/enable collection on any objects pointers  
you store in it that you also want to keep alive.  Maybe that's  
easier to understand.


(Any time you use disableCollectorForPointer is a possible leak, by  
the way.  The object will be rooted until you reenable collection,  
so don't try to reenable collection from within the finalizer of an  
object that the rooted object will keep alive.  That's an  
uncollectable cycle.)


-Ken

On Wed, Oct 15, 2008 at 4:45 PM, Ken Ferry [EMAIL PROTECTED] wrote:
 What I did try was
 'NSPointerFunctionsStrongMemory| 
NSPointerFunctionsObjectPointerPersonality'
 which does work even though some of the pointers aren't objects  
and this

 doesn't seem quite correct but since I'm using GC
 NSPointerFunctionsObjectPointerPersonality seems nearly equivalent  
to
 NSPointerFunctionsOpaquePersonality as long as description isn't  
called.


I see.. I think it's a bug that NSPointerFunctionsStrongMemory| 
NSPointerFunctionsOpaqueMemory is rejected.


It's probably not very future safe to add non-objects with the  
object personality.  You might prefer to use  
NSAllocateCollectable(NSScannedOption) and forego the pointer  
array.  This allocates a chunk of memory that is:


(1) Collected by the collector when unreachable by strong reference  
chain from a gc-root.

(2) Conservatively scanned.

To keep the memory alive when used as the void* contextInfo, you'd  
still need to use -[NSGarbageCollector disableCollectorForPointer:].


The main gotcha is that any stores of gc objects into the buffer  
need to generate write barriers, which are calls into the objective- 
c library that let the collector know that the the buffer has  
changed and needs to be rescanned next time a collection runs.  This  
should Just Work provided the type of the buffer is __strong, but  
you can put doubt to rest by checking that the compiler emitted the  
function calls.  In Xcode, right click and choose Show Assembly  
Code, then look for the calls.  For example, this


- (void)writeToCollectableMemory:(NSObject *)object {
int bufferLength = 5;
__strong void **buffer = (__strong  
void**)NSAllocateCollectable(sizeof(void*)*bufferLength,  
NSScannedOption);

buffer[3] = [[NSObject alloc] init];
…

compiles to this.  objc_assign_strongCast is the function call.

-[MyBlockOperation writeToCollectableMemory:]:
LFB672:
LM221:
LVL93:
pushl   %ebp
LCFI337:
movl%esp, %ebp
LCFI338:
pushl   %esi
LCFI339:
pushl   %ebx
LCFI340:
subl$16, %esp
LCFI341:
callL245
L076$pb:
L245:
popl%ebx
LM222:
movl$1, 4(%esp)
movl$20, (%esp)
call_NSAllocateCollectable
movl%eax, %esi
LM223:
movlL_OBJC_SELECTOR_REFERENCES_3-L076$pb(%ebx), %eax
movl%eax, 4(%esp)
movlL_OBJC_CLASS_REFERENCES_0-L076$pb(%ebx), %eax
movl%eax, (%esp)
call_objc_msgSend
movlL_OBJC_SELECTOR_REFERENCES_4-L076$pb(%ebx), %edx
movl%edx, 4(%esp)
movl%eax, (%esp)
call_objc_msgSend
leal12(%esi), %edx
movl%edx, 4(%esp)
movl%eax, (%esp)
call_objc_assign_strongCast
…

-Ken
Cocoa Frameworks

On Wed, Oct 15, 2008 at 9:32 AM, Michael Link [EMAIL PROTECTED]  
wrote:

 That makes sense, although
 'NSPointerFunctionsStrongMemory|NSPointerFunctionsOpaqueMemory'  
gives the

 error:

 *** -[NSPointerArray initWithOptions:] Requested configuration not
 supported.

 What I did try was
 'NSPointerFunctionsStrongMemory| 
NSPointerFunctionsObjectPointerPersonality'
 which does work even though some of the pointers aren't objects  
and this

 doesn't seem quite correct but since I'm using GC
 NSPointerFunctionsObjectPointerPersonality seems nearly equivalent  
to
 NSPointerFunctionsOpaquePersonality as long as description isn't  
called.


 --
 Michael

 On Oct 15, 2008, at 1:08 AM, Ken Ferry wrote:

 Hi Michael,

 NSPointerFunctionsStrongMemory|NSPointerFunctionsOpaqueMemory  
doesn't
 make sense. You're meant to specify only one of the memory  
options and

 only one of the personality options.

 Due to the way the bitfield work, your invocation is the same as
 NSPointerFunctionsOpaqueMemory|NSPointerFunctionsOpaquePersonality.
 This is the mode in which the pointer array is completely hands- 
off.

 It acts like a C array.

 Try NSPointerFunctionsStrongMemory| 
NSPointerFunctionsOpaquePersonality.

 That sounds right to me, though I get confused with the pointer
 functions too.

 -Ken

 On Tue, Oct 14, 2008 at 9:43 PM, Michael Link [EMAIL PROTECTED]  
wrote:


 I have a situation where I create an NSPointerArray on the stack  
by:


 pointers = [NSPointerArray

 pointerArrayWithOptions:NSPointerFunctionsStrongMemory| 
NSPointerFunctionsOpaqueMemory|NSPointerFunctionsOpaquePersonality];


 I

-[NSGarbageCollection disableCollectorForPointer:] ?

2008-10-14 Thread Michael Link

I have a situation where I create an NSPointerArray on the stack by:

pointers = [NSPointerArray  
pointerArrayWithOptions:NSPointerFunctionsStrongMemory| 
NSPointerFunctionsOpaqueMemory|NSPointerFunctionsOpaquePersonality];


I then go about adding a few objects a selector and a pointer  
(contextInfo that could point to anything even a non-object) to the  
pointer array.


I then call:

[[NSGarbageCollector defaultCollector]  
disableCollectorForPointer:pointers];


The pointer array is then passed as the contextInfo for another method  
(which turns out to be a weak reference), but isn't garbage collected  
due to the previous call. The interesting part turns out that the  
object at index 0 (NSError* in this case) in the pointer array is  
garbage collected (probably because it was a variable in the function  
that called us). The pointer array is configured to use strong  
references therefore index 0 isn't set to NULL and something else is  
located at that memory (sometimes a different object, sometimes  
garbage memory).


If I use:

[[NSGarbageCollector defaultCollector] disableCollectorForPointer: 
[pointers pointerAtIndex:0]];


nothing bad happens and that object isn't collected.

According to the documentation for disableCollectorForPointer:  
shouldn't the pointer array be considered a new root object, and none  
of it's pointers collected? Especially since it uses strong references?


--
Michael
___

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 [EMAIL PROTECTED]


Core Data and Garbage Collection

2008-09-09 Thread Michael Link
I'm running an application with the Core Data thread assertions on and  
am running into some issues on the garbage collection thread.


On the GC thread (#2 usually in GDB), finalizeOneObject() is running  
the finalize method of an NSTextValueBinder object. This object is  
bound to the attribute of an NSManagedObject by way of a couple of  
other objects. From the way the stack trace looks I assume that the  
finalize method of NSTextValueBinder is undoing the observers and in  
the process calls -valueForKey: on the MO (not on the main thread  
where its managed object context lives) and this triggers an assertion  
failure from the MOC.


During -finalize on the GC thread is it allowed to use the MOC from  
the main thread (I wouldn't do this myself)? Or does the binding/ 
observers need to be undone before this reaches GC? I was under the  
impression that observers would be cleaned up automatically.


The binding key path is:

representedObject.fromUser.name

representedObject is an NSManagedObject
fromUser is an NSManagedObject
name is an NSString attribute of fromUser

#0  0x90debbb4 in -[NSAssertionHandler  
handleFailureInMethod:object:file:lineNumber:description:] ()
#1  0x0021d9af in -[NSManagedObjectContext(_NSInternalAdditions)  
_PFAssertSafeMultiThreadedAccess_impl:] ()

#2  0x0015e995 in -[NSManagedObject valueForKey:] ()
#3  0x90d7afa1 in -[NSKeyValueNestedProperty  
object:didRemoveObservance:] ()
#4  0x90d5a203 in -[NSObject(NSKeyValueObserverRegistration)  
_removeObserver:forProperty:] ()
#5  0x90d59fa4 in -[NSObject(NSKeyValueObserverRegistration)  
removeObserver:forKeyPath:] ()
#6  0x90d7afc1 in -[NSKeyValueNestedProperty  
object:didRemoveObservance:] ()
#7  0x90d5a203 in -[NSObject(NSKeyValueObserverRegistration)  
_removeObserver:forProperty:] ()
#8  0x90d59fa4 in -[NSObject(NSKeyValueObserverRegistration)  
removeObserver:forKeyPath:] ()

#9  0x90207b74 in -[NSBinder _updateObservingRegistration:] ()
#10 0x9024e1ef in -[NSBinder  
releaseConnectionWithSynchronizePeerBinders:] ()
#11 0x9024e3f5 in -[NSValueBinder  
releaseConnectionWithSynchronizePeerBinders:] ()

#12 0x903f0ee0 in -[NSBinder finalize] ()
#13 0x91675976 in finalizeOneObject ()
#14 0x92d75dab in foreach_block_do ()
#15 0x91675b3b in batchFinalize ()
#16 0x91675e02 in batchFinalizeOnTwoThreads ()
#17 0x92d76f0e in auto_collect_internal ()
#18 0x92d77b8f in auto_collection_thread ()
#19 0x93f8c6f5 in _pthread_start ()
#20 0x93f8c5b2 in thread_start ()

(gdb) info frame
Stack level 2, frame at 0xb01025f0:
 eip = 0x15e995 in -[NSManagedObject valueForKey:]; saved eip  
0x90d7afa1

 called by frame at 0xb01026c0, caller of frame at 0xb0102590
 Arglist at 0xb01025e8, args:
 Locals at 0xb01025e8, Previous frame's sp is 0xb01025f0
 Saved registers:
  ebx at 0xb01025e0, ebp at 0xb01025e8, esi at 0xb01025e4, eip at  
0xb01025ec

(gdb) po *(int*)(0xb01025e8 + 16)
fromUser
(gdb) info frame
Stack level 13, frame at 0xb0102c60:
 eip = 0x91675976 in finalizeOneObject; saved eip 0x92d75dab
 called by frame at 0xb0102c90, caller of frame at 0xb0102c40
 Arglist at 0xb0102c58, args:
 Locals at 0xb0102c58, Previous frame's sp is 0xb0102c60
 Saved registers:
  ebp at 0xb0102c58, eip at 0xb0102c5c
(gdb) po *(int*)(0xb0102c58 + 8)
NSTextValueBinder: 0x2eb6b90{object: (null), bindings:  
value=representedObject.fromUser.name}

(gdb) c
Continuing.
2008-09-09 17:47:06.883 Spyder[1140:2903] *** Assertion failure in - 
[NSManagedObjectContext _PFAssertSafeMultiThreadedAccess_impl:], / 
SourceCache/Persistence/Persistence-186/NSManagedObjectContext.m:2340
objc[1140]: GC: -finalize resulted in an exception (0x2ec4600) being  
thrown, break on objc_exception_during_finalize_error to debug
	CoreData: warning: Access by another thread to NSManagedObjectContext  
during valueForKey:


--
Michael
___

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 [EMAIL PROTECTED]


NSArrayController bindings and preservesSelection

2008-08-30 Thread Michael Link
I have a situation where I have a source list whose selection controls  
the bindings of an NSArrayController, and thus the content of a view.  
Depending on what source a user selects in the source list the  
NSArrayController can have its MOC bound and a fetch predicate set or  
its contentSet bound to an NSObjectController who is bound to the MOC  
with a fetch predicate set (ideally I'd be using strictly fetch  
predicates which would solve this problem, but it seems that binding  
the array controller to the object controller and setting the  
contentSet key path to selection.toManyRelationship is * faster than  
the equivalent fetch predicate even though it does the same thing).


When the source list selection is changed so that the array  
controllers bindings are changed from contentSet to MOC then the array  
controller does preserve the selection.


If the array controllers bindings are changed from a MOC to a  
contentSet the array controller doesn't seem to preserve the selection  
even though the new content also contains objects that were in the  
selection. I'd like to find a way that the selection can be preserved  
with this change, if possible?


This is the code that manages this process...

@implementation MXBindHistoryItem
@synthesize bindingsInfo = _bindingsInfo;
@synthesize fetchPredicate = _fetchPredicate;

- (id)initWithTitle:(NSString*)title bindings: 
(NSDictionary*)bindingsInfo fetchPredicate:(NSPredicate*)predicate

{
if (self = [super initWithTitle:title]) {
_bindingsInfo = bindingsInfo;
_fetchPredicate = predicate;
}

return self;
}

- (NSDictionary*)_bindingsInfoForController:(id)controller
{
NSMutableDictionary* __bindingsInfo = [NSMutableDictionary dictionary];

for (NSString* __binding in [controller exposedBindings]) {
NSDictionary* __bindingInfo = [controller 
infoForBinding:__binding];

if (__bindingInfo) {
[__bindingsInfo setObject:__bindingInfo 
forKey:__binding];
}
}

return __bindingsInfo;
}

- (void)_unbindController:(id)controller bindingsInfo: 
(NSDictionary*)bindingsInfo

{
if ([bindingsInfo objectForKey:NSManagedObjectContextBinding]) {
[controller setAutomaticallyPreparesContent:NO];

for (NSString* __binding in bindingsInfo) {
[controller unbind:__binding];
}

//  [controller setManagedObjectContext:nil];
//  [controller setFetchPredicate:nil];
}
else {
for (NSString* __binding in bindingsInfo) {
[controller unbind:__binding];
}
}
}

- (void)_bindController:(id)controller
{
for (NSString* __binding in _bindingsInfo) {
NSDictionary* __bindingInfo = [_bindingsInfo 
objectForKey:__binding];

		[controller bind:__binding toObject:[__bindingInfo  
objectForKey:NSObservedObjectKey] withKeyPath:[__bindingInfo  
objectForKey:NSObservedKeyPathKey] options:[__bindingInfo  
objectForKey:NSOptionsKey]];

}
}

- (void)bindController:(id)controller
{
	NSDictionary* __bindingsInfo = [self  
_bindingsInfoForController:controller];


if (![__bindingsInfo count]) {
if ([_bindingsInfo objectForKey:NSManagedObjectContextBinding]) 
{
[self _bindController:controller];
[controller setAutomaticallyPreparesContent:YES];
[controller setFetchPredicate:_fetchPredicate];
[controller fetch:nil];
}
else {
[self _bindController:controller];
}
}
else {
if ([_bindingsInfo objectForKey:NSManagedObjectContextBinding]) 
{
			if ([[_bindingsInfo objectForKey:NSManagedObjectContextBinding]  
objectForKey:NSObservedObjectKey] == [[__bindingsInfo  
objectForKey:NSManagedObjectContextBinding]  
objectForKey:NSObservedObjectKey]) {

[controller setFetchPredicate:_fetchPredicate];
}
else {
[self _unbindController:controller 
bindingsInfo:__bindingsInfo];
[self _bindController:controller];
[controller 
setAutomaticallyPreparesContent:YES];
[controller setFetchPredicate:_fetchPredicate];
}
}
else {
[self _unbindController:controller 
bindingsInfo:__bindingsInfo];
[self _bindController:controller];
}
}
}

@end


___

Cocoa-dev mailing list 

Re: NSArrayController bindings and preservesSelection

2008-08-30 Thread Michael Link
Doh! I must not have had my afternoon hit of caffeine. I was still  
using fetch: instead of fetchWithRequest:merge:error: for the object  
controller which caused the contentSet to be nil (and thus the  
selection to be wiped out) until the fetch was sent the next time  
around the run loop.


--
Michael

On Aug 30, 2008, at 10:00 PM, Michael Link wrote:

I have a situation where I have a source list whose selection  
controls the bindings of an NSArrayController, and thus the content  
of a view. Depending on what source a user selects in the source  
list the NSArrayController can have its MOC bound and a fetch  
predicate set or its contentSet bound to an NSObjectController who  
is bound to the MOC with a fetch predicate set (ideally I'd be using  
strictly fetch predicates which would solve this problem, but it  
seems that binding the array controller to the object controller and  
setting the contentSet key path to selection.toManyRelationship is *  
faster than the equivalent fetch predicate even though it does the  
same thing).


When the source list selection is changed so that the array  
controllers bindings are changed from contentSet to MOC then the  
array controller does preserve the selection.


If the array controllers bindings are changed from a MOC to a  
contentSet the array controller doesn't seem to preserve the  
selection even though the new content also contains objects that  
were in the selection. I'd like to find a way that the selection can  
be preserved with this change, if possible?


This is the code that manages this process...

@implementation MXBindHistoryItem
@synthesize bindingsInfo = _bindingsInfo;
@synthesize fetchPredicate = _fetchPredicate;

- (id)initWithTitle:(NSString*)title bindings: 
(NSDictionary*)bindingsInfo fetchPredicate:(NSPredicate*)predicate

{
if (self = [super initWithTitle:title]) {
_bindingsInfo = bindingsInfo;
_fetchPredicate = predicate;
}

return self;
}

- (NSDictionary*)_bindingsInfoForController:(id)controller
{
	NSMutableDictionary* __bindingsInfo = [NSMutableDictionary  
dictionary];


for (NSString* __binding in [controller exposedBindings]) {
NSDictionary* __bindingInfo = [controller 
infoForBinding:__binding];

if (__bindingInfo) {
[__bindingsInfo setObject:__bindingInfo 
forKey:__binding];
}
}

return __bindingsInfo;
}

- (void)_unbindController:(id)controller bindingsInfo: 
(NSDictionary*)bindingsInfo

{
if ([bindingsInfo objectForKey:NSManagedObjectContextBinding]) {
[controller setAutomaticallyPreparesContent:NO];

for (NSString* __binding in bindingsInfo) {
[controller unbind:__binding];
}

//  [controller setManagedObjectContext:nil];
//  [controller setFetchPredicate:nil];
}
else {
for (NSString* __binding in bindingsInfo) {
[controller unbind:__binding];
}
}
}

- (void)_bindController:(id)controller
{
for (NSString* __binding in _bindingsInfo) {
		NSDictionary* __bindingInfo = [_bindingsInfo  
objectForKey:__binding];


		[controller bind:__binding toObject:[__bindingInfo  
objectForKey:NSObservedObjectKey] withKeyPath:[__bindingInfo  
objectForKey:NSObservedKeyPathKey] options:[__bindingInfo  
objectForKey:NSOptionsKey]];

}
}

- (void)bindController:(id)controller
{
	NSDictionary* __bindingsInfo = [self  
_bindingsInfoForController:controller];


if (![__bindingsInfo count]) {
if ([_bindingsInfo objectForKey:NSManagedObjectContextBinding]) 
{
[self _bindController:controller];
[controller setAutomaticallyPreparesContent:YES];
[controller setFetchPredicate:_fetchPredicate];
[controller fetch:nil];
}
else {
[self _bindController:controller];
}
}
else {
if ([_bindingsInfo objectForKey:NSManagedObjectContextBinding]) 
{
			if ([[_bindingsInfo objectForKey:NSManagedObjectContextBinding]  
objectForKey:NSObservedObjectKey] == [[__bindingsInfo  
objectForKey:NSManagedObjectContextBinding]  
objectForKey:NSObservedObjectKey]) {

[controller setFetchPredicate:_fetchPredicate];
}
else {
[self _unbindController:controller 
bindingsInfo:__bindingsInfo];
[self _bindController:controller];
[controller 
setAutomaticallyPreparesContent:YES];
[controller setFetchPredicate

Re: Core Data merge and statement is still active error?

2008-06-05 Thread Michael Link


On Jun 5, 2008, at 4:37 PM, Ben Trumbull wrote:



On Jun 3, 2008, at 8:15 PM, Michael Link wrote:

Is there a reason you're not using Core Data's - 
mergeChangesFromContextDidSaveNotification: ?


If the object is modified (inserted, update, or deleted), you  
should pass in YES to -refreshObject:mergeChanges:


Actually I am using mergeChangesFromContextDidSaveNotification:, I  
am calling refreshObject:mergeChanges: with NO on the  
NSUpdatedObjectsKey objects just before as this avoids the problem  
of Bug 5937572.


You shouldn't call -refreshObject:mergeChanges:NO on an object with  
changes (passing YES is okay).  The reason for this is if the object  
is deleted or inserted, nuking that state is just plain weird.  The  
graph of objects will not behave they way you would wish.  A nuked  
inserted object is stuck in limbo, and a nuked deleted object can be  
a stale pointer for any of the objects related to it across inverse  
relationships.  Nuking an updated object also has a high probability  
of corrupting the relationship state for other objects with  
relationships to it.


Since the objects on the main thread aren't supposed to have  
changes, skipping the changed ones shouldn't be a burden.


I should skip using -refreshObject:mergeChanges:NO on any object that  
is in NSUpdatedObjectsKey? Even though they don't have changes on the  
main thread? I suppose that makes sense, the original reason for doing  
this was to find a work-around for bug-5937572, which seems to work in  
experimentation (although now without lazy controllers). I'm probably  
just coding myself in a corner I don't want to be in anyways by doing  
this. Ideally I would like to simply use  
mergeChangesFromContextDidSaveNotification: although the merge seems  
to produce the previously mentioned inconsistencies. I even tried  
using -refreshObject:mergeChanges:YES, objectWithID:, and  
deleteObject: to emulate what  
mergeChangesFromContextDidSaveNotification: probably does on the  
userInfo of the notification, but it produced the exact same results  
to no surprise.





At this point we can now look at ObjectA (which is the same as  
ObjectB except it is owned by the main thread's MOC) which will  
show that it has 10 friends. It should have 20 but the merge has  
deleted the 10 friends that were just inserted on the background  
thread, but just for ObjectA. Looking at those 10 objects that were  
deleted on the main thread you will find that they are still  
friends with ObjectA. This leaves the object graph in an  
inconsistent state.


The object on the main thread seems to think it has local changes to  
the friends relationship and during the merge this is trumping the  
changes you've just made in the other context.  I'm still  
investigating the issue with the new example.


That makes sense. Although I wasn't able to see any changes with the  
public methods available to NSManagedObject, I'll assume that's  
happening somewhere private.


I attached the Bug-2 project to bug-5989987 in Bug Reporter which may  
help in the investigation. Also here: http://www.dazys.com/Bug-2.zip


--
Michael


___

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 [EMAIL PROTECTED]


Core Data merge and statement is still active error?

2008-06-03 Thread Michael Link
The goal is to do insertions/changes/deletes on a background thread  
and then after a save merge those changes into the main threads  
managed object context and thus update the UI.


I have a situation where NSManagedObjectContextDidSaveNotification is  
forwarded from a background thread's managed object context to the  
main thread's managed object context (each thread has it's own managed  
object context). The main thread does some processing like this (in a  
subclass of NSPersistentDocument).


- (void)_mergeChangesFromContextDidSaveNotification: 
(NSNotification*)notification

{
	NSManagedObjectContext* __managedObjectContext = [self  
managedObjectContext];
	NSDate* __date = [[[NSFileManager defaultManager]  
fileAttributesAtPath:[[self fileURL] path] traverseLink:YES]  
objectForKey:NSFileModificationDate];


	[__managedObjectContext  
mergeChangesFromContextDidSaveNotification:notification];

[__managedObjectContext processPendingChanges];
[[__managedObjectContext undoManager] enableUndoRegistration];

	NSLog(@%s *1* hasChanges=%d, __FUNCTION__, [__managedObjectContext  
hasChanges]);


[self setFileModificationDate:__date];

if ([__managedObjectContext hasChanges]) {
[self saveDocument:self];
}
}

- (void)mergeChangesFromContextDidSaveNotification: 
(NSNotification*)notification

{
	NSManagedObjectContext* __managedObjectContext = [self  
managedObjectContext];


	NSLog(@%s *0* hasChanges=%d, __FUNCTION__, [__managedObjectContext  
hasChanges]);


if ([__managedObjectContext hasChanges]) {
		NSDate* __date = [[[NSFileManager defaultManager]  
fileAttributesAtPath:[[self fileURL] path] traverseLink:YES]  
objectForKey:NSFileModificationDate];


[self setFileModificationDate:__date];
[self saveDocument:self];
}

[[__managedObjectContext undoManager] disableUndoRegistration];

	for (NSManagedObject* __object in [[notification userInfo]  
objectForKey:NSUpdatedObjectsKey]) {
		[__managedObjectContext refreshObject:[__managedObjectContext  
objectWithID:[__object objectID]] mergeChanges:NO];

}

	[self  
performSelector 
:@selector(_mergeChangesFromContextDidSaveNotification:)  
withObject:notification afterDelay:0.0];

}

If I forgo the refreshObject:mergeChanges: the error doesn't occur,  
but then another problem occurs where sometimes a relationship doesn't  
merge correctly between 2 objects (even when there are no changes in  
the main thread's managed object context the merge will sometimes  
delete part of one side of the relationship. This happens with many-to- 
many relationships including reflexive). By calling  
refreshObject:mergeChanges: I am forcing that object to be faulted and  
re-fetched with the correct data in the store.


It seems that sometimes the call to  
mergeChangesFromContextDidSaveNotification: causes an error that shows  
up in the output as statement is still active. It appears that  
object controllers that are bound to a managed object context receive  
a notification _NSObjectsChangedInManagingContextPrivateNotification  
and they do some fetching and the error occurs when they do a fetch  
request.


I ran with the Core Data threading assertions in the _debug version of  
the library and nothing special is reported.


Has anyone encountered this problem before and found a solution?

--
Michael
___

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 [EMAIL PROTECTED]


Re: Core Data merge and statement is still active error?

2008-06-03 Thread Michael Link


On Jun 3, 2008, at 5:52 PM, Ben Trumbull wrote:


Michael,

This error is almost always a multi-threading problem.  When you  
used the _debug version of Core Data, did you enable the threading  
assertions with the user default -com.apple.CoreData.ThreadingDebug  
3 ?


Yes, I also see this in the console:

2008-06-03 18:26:08.824 Bug5912058[5770:10b] CoreData Multithreading  
assertions enabled.



 What version of OSX are you using ?


I'm using 10.5.3 (9D34), installed  
apple_debug_and_profile_libraries_for_mac_os_x_10.5.3_9d34.mpkg.zip  
yesterday.


 Is there a reason you're not using Core Data's - 
mergeChangesFromContextDidSaveNotification: ?



If the object is modified (inserted, update, or deleted), you should  
pass in YES to -refreshObject:mergeChanges:


Actually I am using mergeChangesFromContextDidSaveNotification:, I am  
calling refreshObject:mergeChanges: with NO on the NSUpdatedObjectsKey  
objects just before as this avoids the problem of Bug 5937572.


Originally I was just using the managed object context's  
mergeChangesFromContextDidSaveNotification: but I noticed that the  
merges weren't reflecting what had been saved in regards to some  
objects relationships. For example:


1. Perform some insertions and changes on a background thread. One of  
these changes is to add the inserted objects to one of the objects  
relationships (which is a many-to-many reflexive relationship). Let's  
say ObjectB which exists in the background thread's MOC now has 20  
friends (10 of the friends are newly inserted and 10 are existing  
objects).
2. The background thread's MOC saves, and is registered to receive  
it's own MOC did save notification which it forwards to the main  
thread using performSelectorOnMainThread:
3. The main thread's MOC has no changes and is fed the save  
notification by calling mergeChangesFromContextDidSaveNotification:  
and passing the notification.


At this point we can now look at ObjectA (which is the same as ObjectB  
except it is owned by the main thread's MOC) which will show that it  
has 10 friends. It should have 20 but the merge has deleted the 10  
friends that were just inserted on the background thread, but just for  
ObjectA. Looking at those 10 objects that were deleted on the main  
thread you will find that they are still friends with ObjectA. This  
leaves the object graph in an inconsistent state.






It seems that sometimes the call to
mergeChangesFromContextDidSaveNotification: causes an error that  
shows

up in the output as statement is still active. It appears that
object controllers that are bound to a managed object context receive
a notification  
_NSObjectsChangedInManagingContextPrivateNotification

and they do some fetching and the error occurs when they do a fetch
request.


This implies you're modifying a MOC on a background thread that's  
bound into Cocoa Bindings.  Cocoa Bindings and much of AppKit expect  
to effectively own their objects on the main thread.  Whichever MOC  
the object controllers are observing is probably being misused.




The controllers are bound to the MOC on the main thread. The  
statement is still active exception occurs in the call to  
mergeChangesFromContextDidSaveNotification: on the main thread's MOC.


I have an Xcode project that can show both bug 5937572, where the  
object graph is left in an inconsistent state after a merge and bug  
5982319, where the statement is still active exception occurs during  
a merge. The project is already attached to bug 5982319 (Bug-1.zip)  
and is setup to show the behavior regarding that issue. To see the  
other issue comment out lines 154-189 and uncomment lines 193-237 in  
MyDocument.m


I also have the archive project here: http://www.dazys.com/Bug-1.zip

--
Michael

___

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 [EMAIL PROTECTED]


transient attributes of NSManagedObject reflected in isUpdated

2008-04-29 Thread Michael Link
I noticed that if you have a transient attribute in an NSManagedObject  
and update that attribute then isUpdated will return that the object  
has unsaved changes. I suppose this makes some sense if the attribute  
is actually defined in the entity. On the other hand if the managed  
object has a subclass and a custom instance variable and a setter  
method such as (using GC):


@property(assign) NSImage* iconImage;

- (void)setIconImage:(NSImage*)value
{
// isUpdated returns 0
[self willChangeValueForKey:@iconImage];
_iconImage = value;
[self didChangeValueForKey:@iconImage];
// isUpdated returns 1
}

The attribute isn't in the model and I don't really want Core Data to  
know anything about it because it can't be saved in the store etc...


After this method is used isUpdated will return that the object has  
unsaved changes, even though the attribute isn't part of the model and  
changedValues is empty (since it's quite transient). My guess would be  
that didChangeValueForKey: always sets a flag that marks the object as  
being updated (even though none of the changes can be saved, and funny  
enough when I quit the application is asks me if I want to save the  
unsaved changes).


I'm trying to avoid having the object marked as updated because it  
causes some issues with sorting being quite inaccurate for an  
NSArrayController that uses lazy binding.


Is there anyway to set a custom instance variable in an  
NSManagedObject subclass by still being key-value friendly and not  
marking the object as updated?


--
Michael

___

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 [EMAIL PROTECTED]