Fri 27 Jun 2008 01:01:44 PM UTC, original submission:
Hi all,
I have two issues, and I am not sure that either of them is a bug, but at least the documentation is not clear.
The first is about the keys used in an NSDictionary. As far as I understand the documentation of NSDictionary, I should be able to use keys that are instances of different classes (say an NSString and an NSNumber key). The only requirement that is implicit in the doc is that -isEqual should recognize the object. If I try to use such keys, it works fine as long as I do not want to print the dictionary. The functions converting the dictionary to string die, because one of them calls -compare on two keys, which does not exist for different classes. Now, either it should be forbidden (strongly and explicitely discouraged) to use keys of different types, or it should be required that a -compare method exists, or the conversion functions should not try to compare.
Here is the code reproducing the error:
#include <Foundation/Foundation.h>
int main(){
CREATE_AUTORELEASE_POOL(pool);
NSString *key1 = @"one";
NSNumber *key2 = [NSNumber numberWithInt: 2];
NSString *value1 = @"firstValue";
NSString *value2 = @"secondValue";
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject: value1 forKey: key1];
[dict setObject: value2 forKey: key2];
@try {
NSLog(@"dictionary: %@", dict);
}@catch (NSException *e){
NSLog(@"%@", e);
}
[pool release];
return 0;
}
And here is the backtrace from gdb:
(gdb) r
Starting program: /home/mahr/src/NSDictionaryTest/obj/printTest
[Thread debugging using libthread_db enabled]
[New Thread -1208538384 (LWP 4627)]
Program received signal SIGABRT, Aborted.
[Switching to Thread -1208538384 (LWP 4627)]
0x00296402 in __kernel_vsyscall ()
(gdb) bt
#0 0x00296402 in __kernel_vsyscall ()
#1 0x00129ba0 in raise () from /lib/libc.so.6
#2 0x0012b4b1 in abort () from /lib/libc.so.6
#3 0x0071d71f in objc_exception_throw () from /usr/lib/libobjc.so.1
#4 0x008690f1 in -[NSException raise] (self=0xa09be80, _cmd=0xb2e6b8) at NSException.m:806
#5 0x00868c3a in +[NSException raise:format:arguments:] (self=0xb2e160, _cmd=0xb2e6a0, name=0xb2dedc, format=0xb3fa8c, argList=0xbfba668c "^ͳ")
at NSException.m:753
#6 0x00868b72 in +[NSException raise:format:] (self=0xb2e160, _cmd=0xb40450, name=0xb2dedc, format=0xb3fa8c) at NSException.m:739
#7 0x008a70c1 in -[NSObject doesNotRecognizeSelector:] (self=0x9ffb240, _cmd=0xb40548, aSelector=0xb14288) at NSObject.m:1672
#8 0x008a729d in -[NSObject forwardInvocation:] (self=0x9ffb240, _cmd=0x9fcaf90, anInvocation=0xa09b300) at NSObject.m:1700
#9 0x0094a186 in GSInvocationCallback (callback_data=0xb834f0, args=0xbfba6814) at GSFFCallInvocation.m:975
#10 0x00e31815 in __vacall_r () from /usr/lib/libcallback.so.0
#11 0x00b834f0 in returnTypeInfo () from /usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14
#12 0xbfba6814 in ?? ()
#13 0x00000004 in ?? ()
#14 0xbfba6848 in ?? ()
#15 0x00000000 in ?? ()
(gdb) up
#1 0x00129ba0 in raise () from /lib/libc.so.6
(gdb)
#2 0x0012b4b1 in abort () from /lib/libc.so.6
(gdb)
#3 0x0071d71f in objc_exception_throw () from /usr/lib/libobjc.so.1
(gdb)
#4 0x008690f1 in -[NSException raise] (self=0xa09be80, _cmd=0xb2e6b8) at NSException.m:806
806 @throw self;
(gdb)
#5 0x00868c3a in +[NSException raise:format:arguments:] (self=0xb2e160, _cmd=0xb2e6a0, name=0xb2dedc, format=0xb3fa8c, argList=0xbfba668c "^ͳ")
at NSException.m:753
753 [except raise];
(gdb) po except
<NSException: 0xa09be80> NAME:NSInvalidArgumentException REASON:GSCachedInt(instance) does not recognize length INFO:{GSStackTraceKey = " 0: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0x12f1e6) +[GSStackTrace currentStack] /home/mahr/src/gnustep-base-1.14.1/Source/NSException.m: 511
1: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0x1300c9) -[NSException raise] /home/mahr/src/gnustep-base-1.14.1/Source/NSException.m: 801
2: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0x12fc3a) +[NSException raise:format:arguments:] /home/mahr/src/gnustep-base-1.14.1/Source/NSException.m: 754
3: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0x12fb72) +[NSException raise:format:] /home/mahr/src/gnustep-base-1.14.1/Source/NSException.m: 742
4: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0x16e0c1) -[NSObject doesNotRecognizeSelector:] /home/mahr/src/gnustep-base-1.14.1/Source/NSObject.m: 1677
5: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0x16e29d) -[NSObject forwardInvocation:] /home/mahr/src/gnustep-base-1.14.1/Source/NSObject.m: 1702
6: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0x211186) GSInvocationCallback /home/mahr/src/gnustep-base-1.14.1/Source/GSFFCallInvocation.m: 978
7: (/usr/lib/libcallback.so.0: 0x815) __vacall_r (nil): 0
8: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0xad3d0) compare_c /home/mahr/src/gnustep-base-1.14.1/Source/GSString.m: 1200
9: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0xad22e) -[GSCString compare:options:range:] /home/mahr/src/gnustep-base-1.14.1/Source/GSString.m: 2821
10: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0x1c0700) -[NSString compare:options:] /home/mahr/src/gnustep-base-1.14.1/Source/NSString.m: 1755
11: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0x1c0668) -[NSString compare:] /home/mahr/src/gnustep-base-1.14.1/Source/NSString.m: 1741
12: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0x19587a) OAppend /home/mahr/src/gnustep-base-1.14.1/Source/NSPropertyList.m: 2244
13: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0x1969ff) GSPropertyListMake /home/mahr/src/gnustep-base-1.14.1/Source/NSPropertyList.m: 2506
14: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0x1269c4) -[NSDictionary descriptionWithLocale:indent:] /home/mahr/src/gnustep-base-1.14.1/Source/NSDictionary.m: 1056
15: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0x126958) -[NSDictionary descriptionWithLocale:] /home/mahr/src/gnustep-base-1.14.1/Source/NSDictionary.m: 1037
16: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0x964c8) GSPrivateFormat /home/mahr/src/gnustep-base-1.14.1/Source/GSFormat.m: 1862
17: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0xab785) -[GSPlaceholderString initWithFormat:locale:arguments:] /home/mahr/src/gnustep-base-1.14.1/Source/GSString.m: 717
18: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0x1bbdd8) -[NSString initWithFormat:arguments:] /home/mahr/src/gnustep-base-1.14.1/Source/NSString.m: 1051
19: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0x214b4d) +[NSString(GSCategories) stringWithFormat:arguments:] /home/mahr/src/gnustep-base-1.14.1/Source/Additions/GSCategories.m: 1100
20: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0x15a02e) NSLogv /home/mahr/src/gnustep-base-1.14.1/Source/NSLog.m: 346
21: (/usr/GNUstep/System/Library/Libraries/libgnustep-base.so.1.14: 0x159c27) NSLog /home/mahr/src/gnustep-base-1.14.1/Source/NSLog.m: 255
22: (/home/mahr/src/NSDictionaryTest/obj/printTest: 0x8048925) main /home/mahr/src/NSDictionaryTest/printTest.m: 18
23: (/lib/libc.so.6: 0x116dec) __libc_start_main (nil): 0
24: (/home/mahr/src/NSDictionaryTest/obj/printTest: 0x8048711) _start (nil): 0
"; }
(gdb)
My second question relates to the exception in the previous example.
As you can see, the NSInvalidExecption is not catched by the @try{}@catch{} blocks. I suspect here the forwarding mechanism. I use the forwardInvocation mechnism in my project and I think I can see the tendency that exceptions are not caught once the call-chain includes a forwardInvocation: call. Can somebody please explain it to me why is that?
Thank You!
Tamas
|