Re: [Pyobjc-dev] In and out of NSData
Brought to you by:
ronaldoussoren
From: Ronald O. <ous...@ci...> - 2003-01-10 21:30:04
|
On Wednesday, Jan 8, 2003, at 07:40 Europe/Amsterdam, Ronald Oussoren wrote: > > On Tuesday, Jan 7, 2003, at 16:30 Europe/Amsterdam, Bob Ippolito wrote: > >> I updated to latest CVS.. it seems that you may now initialize >> NSData/NSMutableData with a python string or an array, but it breaks >> for big ones. >> >> >>> from Foundation import * >> >>> import array >> >>> bytes = array.array('b', 'abcdef') >> >>> NSData.alloc().initWithBytes_length_(bytes, len(bytes)) >> <a07e> >> >>> NSMutableData.alloc().initWithBytes_length_(bytes, len(bytes)) >> <a07eda48 00000001 00000000 00000054 007db1e0 00000000 00000000 >> 00000001 76304034 3a385e76 31324931 36000001 76304034 3a384931 >> 32000000 00010002 76> >> >>> bytes = array.array('b', 'abcdef' * 1000) >> >>> NSData.alloc().initWithBytes_length_(bytes, len(bytes)) >> Segmentation fault >> > > You can work around this by using 'NSData.dataWithBytes_length_' for > now. There seems to be a problem with reference counts (based on a > quick glance at a traceback in gdb), the segfault is caused by the > release of 'self' when deallocating the bound method > 'initWithBytes_length_', and this self doesn't have a valid 'isa' > pointer. I found where this problem originates: inside Cocoa :-(. I can probably get a simular crash using pure objective-C code (I've not tested this, hence the 'probably'). { id initial = nil; id post = nil; initial = [NSData alloc]; post = [initial initWithBytes:"XXX ... repeat as needed" len:30]; // here 'initial' is no longer a pointer to a valid object ... [initial description]; // CRASH } I've observed the the corruption of 'initial' by adding an appropriate NSLog after the call to initWithBytes in Modules/Cocoa/_FoundationMapping_NSData. I think this is a feature of Cocoa that is needed to avoid leaks with the idiom [[NSData alloc] initWithBytes:foo len:bar], because NSData is a class-cluster the result of [NSData alloc] cannot be the same object as the one returned by initWithBytes:len:. Actually, [NSData alloc] seems to return an empty NSConcreteData object, that's probably why it only fails with a large-enough buffer. Sadly enough just bracketing the call to initWithBytes with [self retain] and [self release] doesn't help: I then get a abort() on the call to [self release]: calling method of a freed object. My current workaround: Just set the pointer inside the proxy object to NULL. I'll check this in after verifying that this won't cause problems later on. Ronald |