|
View:
New views
6 Messages
—
Rating Filter:
Alert me
|
|
|
Problems with Replacing a String is a NSMutableStringHello:
I am currently having a problem with replacing a string in an NSMutableString and I am not too sure whether it is a bug in the current SVN tree or I am doing something stupid. Here are the code snippets: ... NSMutableString *albumIndexTemp; ... // PlayItem is just a dictionary of strings. Since there is // only 1 key with the value of "Album". The first index of // the array should return something like // "ID_CLIP_INFO_NAME4". albumIndexTemp = [[playingItem allKeysForObject:@"Album"] objectAtIndex: 0]; // This should return something like "ID_CLIP_INFO_VALUE4" [albumIndexTemp replaceOccurrencesOfString:@"NAME" withString:@"VALUE"]; [albumBox setStringValue:[playingItem objectForKey:albumIndexTemp]]; [albumBoxMini setStringValue:[playingItem objectForKey:albumIndexTemp]]; ---------------------------------------------------------------------- However, this doesn't seem to work. I have a similiar stanza above (without the string replacement) and it worked: if ([[playingItem objectForKey:@"ID_CLIP_INFO_NAME1"] isEqual:@"Artist"]) { [artistBox setStringValue:[playingItem objectForKey:@"ID_CLIP_INFO_VALUE1"]]; [artistBoxMini setStringValue:[playingItem objectForKey:@"ID_CLIP_INFO_VALUE1" } --------------------------------------------------- What am I doing wrong? Thanks. Charles _______________________________________________ Discuss-gnustep mailing list Discuss-gnustep@... http://lists.gnu.org/mailman/listinfo/discuss-gnustep |
|
|
Re: Problems with Replacing a String is a NSMutableStringHello Charles,
Charles philip Chan schrieb: > I am currently having a problem with replacing a string in an > NSMutableString and I am not too sure whether it is a bug in the current > SVN tree or I am doing something stupid. Here are the code snippets: > ... > NSMutableString *albumIndexTemp; > ... > // PlayItem is just a dictionary of strings. Since there is > // only 1 key with the value of "Album". The first index of > // the array should return something like > // "ID_CLIP_INFO_NAME4". > albumIndexTemp = [[playingItem allKeysForObject:@"Album"] > objectAtIndex: 0]; > > // This should return something like "ID_CLIP_INFO_VALUE4" > [albumIndexTemp replaceOccurrencesOfString:@"NAME" > withString:@"VALUE"]; > > What am I doing wrong? I would assume that if playingItem is an NS[(Mutable)Dictionary that the key returned by allKeysForObject: are immutable. Keys for collections are copied by the collection to insure they are immutable. Allowing them to be mutable would break the internal hash lookups. Cheers, David _______________________________________________ Discuss-gnustep mailing list Discuss-gnustep@... http://lists.gnu.org/mailman/listinfo/discuss-gnustep |
|
|
Re: Problems with Replacing a String is a NSMutableStringDavid Ayers <ayers@...> writes:
Hello David: > I would assume that if playingItem is an NS[(Mutable)Dictionary that the > key returned by allKeysForObject: are immutable. Keys for collections > are copied by the collection to insure they are immutable. Allowing > them to be mutable would break the internal hash lookups. I still don't understand this, the method "allKeysForObject" is supposed to: ,---- | Returns an array containing all the dictionary's keys that are | associated with anObject.[1] `---- So basically I am returning an array of the keys, and since there is only 1 key for the object "Album" I search for it at index zero in the array and return it as an NSMutableString. I then want to change the string to the really key for the "Album" title and search the dictionary for the object- I am not even touching the dictionary. Also "playingItem" is defined as mutable: ,---- | NSMutableDictionary *playingItem = myPlayingItem; `---- Thanks for your reply. Charles --- [1] From http://www.gnustep.org/resources/documentation/Developer/Base/Reference/NSDictionary.html#method$NSDictionary-allKeysForObject$ _______________________________________________ Discuss-gnustep mailing list Discuss-gnustep@... http://lists.gnu.org/mailman/listinfo/discuss-gnustep |
|
|
Re: Problems with Replacing a String is a NSMutableStringOn 24 Jul 2008, at 09:20, Charles philip Chan wrote:
> So basically I am returning an array of the keys, and since there is > only 1 key for the object "Album" I search for it at index zero in the > array and return it as an NSMutableString. I then want to change the > string to the really key for the "Album" title and search the > dictionary > for the object- I am not even touching the dictionary. Also > "playingItem" is defined as mutable: I think the problem is that you are misunderstanding the Objective-C type system. The type of an object is a property of the object itself, not of the label of the object (as it is in languages like C+ +, modulo structural typing). When you insert an object into a dictionary, the key will be immutable, the object may be mutable. When you call allKeysForObject: you get an NSArray (immutable) containing pointers to NSStrings (also immutable). You can not 'return it as an NSMutableString,' you return it as an id, because that is what the objectAtIndex: method on NSArray returns. When you do something like this: id a = {whatever}; NSMutableString *b = a; You are not changing a into an NSMutableString, you are just providing a hint to the compiler that you expect a to respond to any messages declared on NSMutableString. If it does, at runtime, possibly using forwarding, then this will work. If it doesn't, then you will have problems, most likely runtime exceptions from unrecognised selectors. You can not modify the key of an item in an NSDictionary, because that would alter the mappings without NSDictionary knowing that they had altered. When you later did objectForKey: on the dictionary, NSDictionary would call -hash on the key you passed in. It would then look in the bucket associated with this hash and fail to find the key, because it put the key in the bucket corresponding to the return value of -hash when it was entered. The documentation on NSObject tells you that the return value from -hash may not change when an object is in a collection. Looking at your code, it seems that you don't actually want to change the key in the dictionary, you want to change a copy of it. The easiest way to do this is to just send a mutableCopy message, like this: albumIndexTemp = [[[playingItem allKeysForObject:@"Album"] objectAtIndex: 0] mutableCopy]; This will not modify the dictionary state, and will give you an NSMutableString you can do things with. For tracking down this kind of bug (and ensuring it doesn't get reintroduced), you might find this macro that I use with Étoilé useful: #ifdef DEBUG #define SAFECAST(type, obj) ([obj isKindOfClass:[type class]] \ ? (type*)obj \ : ([NSException raise:@"InvalidCast"\ format:@"Can not cast %@ to %s", obj,\ #type], (type*)nil)) #else #define SAFECAST(type, obj) (type*)obj #endif Use it like this: albumIndexTemp = SAFECAST(NSMutableString, [[playingItem allKeysForObject:@"Album"] objectAtIndex: 0]); If you compile in debug mode, this will insert an -isKindOfClass: test and throw an exception (which you can find in the debugger easily) if you are trying to cast an object pointer to an incorrect type. If you compile in release mode then you will get a pointer cast, which has no run time overhead. David _______________________________________________ Discuss-gnustep mailing list Discuss-gnustep@... http://lists.gnu.org/mailman/listinfo/discuss-gnustep |
|
|
Re: Problems with Replacing a String is a NSMutableStringOn 24.07.2008, at 10:20, Charles philip Chan wrote:
>> Keys for collections are copied ^^^ ^^^^^ >> by the collection to insure they are immutable. Allowing them to be >> mutable would break the internal hash lookups. > I still don't understand this ... > | Returns an array containing all the dictionary's keys that are ^^^^ > > | associated with anObject.[1] > `---- > > So basically I am returning an array of the keys, and since there is > only 1 key for the object "Album" I search for it at index zero in the > array and return it as an NSMutableString. Dictionary keys are never NSMutableString objects. As David says, the NSMutableString will get copied when its used as a dictionary key. NSString *key = [NSMutableString stringWithString:@"bla"]; [yourDict setObject:@"this and that" forKey:key]; // the yourDict has no reference to your 'key' object, // it made a copy Aproximately this happens from a copy-perspective: NSString *key = [NSMutableString stringWithString:@"bla"]; NSString *dictCopy; dictCopy = [key copy]; [yourDict setObject:@"this and that" forKey:dictCopy]; [dictCopy release]; As mentioned by David a mutable object can't be used as a hashtable key for rather obvious reasons :-) (if not, lookup hashtable in Wikipedia :-) NSMutableDictionary ensures the immutability by calling -copy. Helge -- Helge Hess http://helgehess.eu/ _______________________________________________ Discuss-gnustep mailing list Discuss-gnustep@... http://lists.gnu.org/mailman/listinfo/discuss-gnustep |
|
|
Re: Problems with Replacing a String is a NSMutableStringDavid Chisnall writes:
> I think the problem is that you are misunderstanding the Objective-C > type system. The type of an object is a property of the object itself, > not of the label of the object (as it is in languages like C+ +, > modulo structural typing). Yes. This was indeed my problem. > You can not modify the key of an item in an NSDictionary, because that > would alter the mappings without NSDictionary knowing that they had > altered. When you later did objectForKey: on the dictionary, > NSDictionary would call -hash on the key you passed in. It would then > look in the bucket associated with this hash and fail to find the key, > because it put the key in the bucket corresponding to the return value > of -hash when it was entered. The documentation on NSObject tells you > that the return value from -hash may not change when an object is in a > collection. Now I am clear on that. > Looking at your code, it seems that you don't actually want to change > the key in the dictionary, you want to change a copy of it. Yes. This is where I misunderstood David Ayers. > For tracking down this kind of bug (and ensuring it doesn't get > reintroduced), you might find this macro that I use with Etoile > useful: Thanks. With you help, I got it working. The only problem is that I still think that there is a bug with "replaceOccurrencesOfString: withString:". I tried it with one of Nicola's tutorials and as with my code, I got a: ,---- | : Uncaught exception NSInvalidArgumentException, reason: Can not | determine type information for -[GSMutableString | replaceOccurrencesOfString:withString:] | Aborted `---- However, once I replace it with the non-standard "replaceString: withString:", it worked. Thank you everyone for your help. Charles _______________________________________________ Discuss-gnustep mailing list Discuss-gnustep@... http://lists.gnu.org/mailman/listinfo/discuss-gnustep |
| Free Forum Powered by Nabble | Forum Help |