• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Debugging "attempt to insert nil value" on customer's machine
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Debugging "attempt to insert nil value" on customer's machine


  • Subject: Re: Debugging "attempt to insert nil value" on customer's machine
  • From: Ondra Cada <email@hidden>
  • Date: Tue, 14 Sep 2004 15:28:52 +0200

Gideon,

On 14.9.2004, at 11:40, Gideon King wrote:

Due to the fact that a class cluster is used, I can't do anything with NSMutableDictionary itself. The concrete class that is identified in the error is a subclass of NSMutableDictionary called NSCFDictionary. This is a private class, so I used class dump to get the interface and subclassed it and used poseAsClass to try to use my own class, which has its own version of setObject:forKey:

My subclass method never gets called, even if I put the poseAsClass: before NSApplicationMain();

try +load, that's as soon as reasonably possible.

The exception message does change though to:

*** -[%NSCFDictionary setObject:forKey:]: attempt to insert nil value

(notice the %) leading me to believe that the runtime system does know something about the posed class. It therefore appears that there is something going on behind the scenes here, which I don't understand.

Me neither, but I *suspect* (really do *not* know) those CoreFoundation "toll-free bridged" uglies are not quite ObjC classes and just don't support poseAsClassing (and more) properly. At least, they did bring havoc to the mutability concept and class distinctions, and it is quite plausible suspection they broke much more :(((


This solution is the one suggested in the archives, but doesn't work for me, and the person who originally suggested it no longer recalls how he got it to work.
I would welcome any suggestions of ways to implement something that will allow me to log the information that will allow me to find and fix the problem.

One possible thing might be to mess directly with the runtime structures (i.e., to change the appropriate method_imp). Here's the generic method to do so:


+(IMP)replaceSelector:(SEL)oldSel ofClass:(Class)oldCl by:(SEL)newSel ofClass:(Class)newCl {
void _objc_flush_caches(Class); // get rid of the warning
IMP original=[oldCl instanceMethodForSelector:oldSel]; // original to remember
if (!original) {
[self logFail:@"cannot find implementation for '%@' in %@",NSStringFromSelector(oldSel),NSStringFromClass(oldCl)];
return NULL;
}
struct objc_method *method=class_getInstanceMethod(oldCl,oldSel); // original to change
if (!method) {
[self logFail:@"cannot find method for '%@' in %@",NSStringFromSelector(oldSel),NSStringFromClass(oldCl)];
return NULL;
}
IMP new=[newCl instanceMethodForSelector:newSel]; // new method to use
if (!new) {
[self logFail:@"cannot find implementation for '%@' in %@",NSStringFromSelector(newSel),NSStringFromClass(newCl)];
return NULL;
}
method->method_imp=new;
_objc_flush_caches(oldCl);
return original;
}


That well might fail with CF-thingies too, though. If so, well... do you happen to know which method is used to create the dictionary in question? If so, you can replace the dictionary by your own subclass on the decent ObjC level, without having to dive into the CoreFoundation swamp:

@implementation PosedAsDictionary:NSMutableDictionary
-(NSMutableDictionary*)dictionary { // or another method
  return [[[MyOwnDictionary alloc] init] autorelease];
}
+(void)load {
  [self poseAsClass:[self superclass]];
}
@end

@interface MyOwnDictionary:NSMutableDictionary {
    NSMutableDictionary *md;
}
@end
@implementation MyOwnDictionary
-(void)setObject:o forKey:key {
  if (!o || !key) WHATEVER...
  [super setObject:o forKey:key];
}
-(unsigned)count {return [md count];}
-objectForKey:k {return [md objectForKey:k];}
-(NSEnumerator*)keyEnumerator {return [md keyEnumerator];}
-(void)setObject:o forKey:k {
    if (!md) md=[[NSMutableDictionary alloc] init];
    [md setObject:o forKey:k];
}
-(void)removeObjectForKey:k {[md removeObjectForKey:k];}
-(void)dealloc {
    [md release];
    [super dealloc];
}
@end

If this does not help either, sorry: no more ideas at the moment...
---
Ondra Čada
OCSoftware:     email@hidden               http://www.ocs.cz
private         email@hidden             http://www.ocs.cz/oc

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: Debugging "attempt to insert nil value" on customer's machine
      • From: Gideon King <email@hidden>
References: 
 >Debugging "attempt to insert nil value" on customer's machine (From: Gideon King <email@hidden>)

  • Prev by Date: NSUndoManager in non-document based app using bindings
  • Next by Date: Re: Embedding other WebViews?
  • Previous by thread: Debugging "attempt to insert nil value" on customer's machine
  • Next by thread: Re: Debugging "attempt to insert nil value" on customer's machine
  • Index(es):
    • Date
    • Thread