NSMapTable Errors

I have a couple apps, and one of them is really prone to crashing with NSMapTable errors. I actually had this happen while debugging the latest version of that Bad App. Does anyone have any idea what’s so prone to happen with NSMapTable?
I thought I read on the XCode list it was an Apple bug, but I forget where I saw that now. And I want to run this by you in this list, the Cocoa/xCode list is a harsh place.
Here’s the debugger output when it crashed:

2011-01-11 18:52:41.356 Coupon Exporter[19193:8e53] An uncaught exception was raised
2011-01-11 18:52:41.356 Coupon Exporter[19193:8e53] *** -[NSMapTable NSMapTable {
}
] count underflow
2011-01-11 18:52:41.383 Coupon Exporter[19193:8e53] *** Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘*** -[NSMapTable NSMapTable {
}
] count underflow’
*** Call stack at first throw:
(
0 CoreFoundation 0x00007fff80313cc4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x00007fff840390f3 objc_exception_throw + 45
2 CoreFoundation 0x00007fff80313ae7 +[NSException raise:format:arguments:] + 103
3 CoreFoundation 0x00007fff80313a74 +[NSException raise:format:] + 148
4 Foundation 0x00007fff82556bf0 -[NSConcreteMapTable rehashAround:] + 447
5 Foundation 0x00007fff82536e0f probeGC + 546
6 Foundation 0x00007fff8254d307 -[NSConcreteMapTable removeObjectForKey:] + 60
7 Foundation 0x00007fff8255c061 -[__NSOperationInternal start] + 681
8 Foundation 0x00007fff8255bd17 ____startOperations_block_invoke_2 + 99
9 libSystem.B.dylib 0x00007fff832211b0 _dispatch_call_block_and_release + 15
10 libSystem.B.dylib 0x00007fff831ff751 _dispatch_worker_thread2 + 239
11 libSystem.B.dylib 0x00007fff831ff088 _pthread_wqthread + 353
12 libSystem.B.dylib 0x00007fff831fef25 start_wqthread + 13
)
terminate called after throwing an instance of ‘NSException’

NSMapTable? And what made you decide to use this instead of NSDictionary? Just curious. :slight_smile:

I see in the docs that it has a strong relationship with garbage collection, maybe there is a clash with ASOC? I remember ASOC using GC, but maybe in this case there is a bug that prevents using this class in ASOC… thinking out loud here.

Browser: Safari 531.22.7
Operating System: Mac OS X (10.6)

That’s my question, too.

heh that’s the thing. I am NOT explicitly calling NSMapTable nor using an NSDictionary.
I have a compound list that displays some information in a table view. It’s like {{title:“document1”,status:“OK”},{title:“document2”,status:“bad”},…}
From reading Shane’s book I think I am doing sort of a klunky implementation of tables.
I’m busy now but will post some more details about how I have it set up.

In Cocoa terms, that’s an array of dictionaries. I suppose it’s possible that Cocoa is using an NSMapTable to implement some of the dictionary handling, but I suspect it’s more likely something like a bindings problem. Whatever, we’d need to at least see some code to be able to offer any useful hints. (And yes, that list is indeed a harsh place…)

here’s some code example from my app:



script Coupon_ExporterAppDelegate
	property parent : class "NSObject"
	property NSTimer : class "NSTimer"
	property NSWindowController : class "NSWindowController"
	
	--IBOutlets
	property ceWindow : missing value
	...
	property ceStartAutoBN : missing value
	property ceDoneFileTableView : missing value --connected to table view

        --Properties, constants
	property myDoneFilesList : {} --data = {procFolder:t, procFNum:u, procErrs:v, procMsg:w}

        --so then there is a lot of things that go on, and when we need to report the functions are done and put things in the UI so users can see what is going on, we call the next function:

--function that updates the table via updating my 
on reportSuccessRateInUI_(successFiles, fileCount, bookIssue)
		if (fileCount - successFiles) > 0 then
			set theMsg to ("Errors - " & (round (100 - ((successFiles / fileCount) * 100))) & "%") as string
		else
			set theMsg to "OK"
		end if
		set my myDoneFilesList to {{procFolder:bookIssue, procFNum:fileCount, procErrs:(fileCount - successFiles), procMsg:theMsg}} & my myDoneFilesList
	end reportSuccessRateInUI_


In the XIB file, there is an Array Controller. The AC’s ContentArray is bound to myDoneFilesList, modelKeyPath = myDoneFilesList. The table’s columns Value are bound to the ArrayController’s - arrangedObjects - modelKeyPath:procFolder or procFNum etc.

Try using a temporary list, so this:

      set my myDoneFilesList to {{procFolder:bookIssue, procFNum:fileCount, procErrs:(fileCount - successFiles), procMsg:theMsg}} & my myDoneFilesList

becomes:

      set tempList to {{procFolder:bookIssue, procFNum:fileCount, procErrs:(fileCount - successFiles), procMsg:theMsg}} & my myDoneFilesList
      set my myDoneFilesList to tempList

I’m not sure what you mean by this statement. I assume that the your AC’s content array is bound to your AppDelegate and not myDoneFilesList (with the modelKeyPath = myDoneFilesList). I copied and pasted the code you posted, and made up some values for fileCount, successFiles, and bookIssue. The table worked fine, and I got no errors, so maybe the problem is elsewhere in your code.

Ric

@rdelmar: It’s not an immediate problem that comes up at every run. It usually happens after the app has been running for a while and has processed from 3-20 jobs. Most days on most computers it never comes up at all.
About the myDoneFilesList, yeah you are correct, sorry my description was a tad off. Connected to the app delegate, MKP=myDoneFilesList