)I've already reported this bug and raised a DTS incident to get it looked at, but I'm also putting it out there in case anyone else runs into it, or can suggest a workaround within app code. (Bug # 35926492)
10.13.2 breaks the function [-NSKeyedDearchiver decodeArrayOfObjCType:count:at:] when the obj-C type is @encode(float) ("f"). It now throws an exception as follows: *** -[_NSKeyedCoderOldStyleArray initWithCoder:]: unable to decode element in array of size (4) and count (6).
Note that all OS up to 10.13.1 work fine.
A test project reproduces the issue with the following code:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSString* path = [@"~/Desktop/testArchive.plist" stringByExpandingTildeInPath];
float testValues[] = {1.0, 2.0, 3.5, 4.6, 3.1415926, 0.0};
NSMutableData* testArchive = [NSMutableData data];
NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:testArchive];
[archiver encodeArrayOfObjCType:@encode(float) count:6 at:testValues];
[archiver finishEncoding];
[testArchive writeToFile:path atomically:YES];
// now read it back in and see if it can be dearchived - in 10.13.2, this will throw an exception.
NSData* readArchive = [NSData dataWithContentsOfFile:path];
NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:readArchive];
float readValues[6];
[unarchiver decodeArrayOfObjCType:@encode(float) count:6 at:readValues]; //<--- throws
[unarchiver finishDecoding];
for( int i = 0; i < 6; ++i )
NSAssert( readValues[i] == testValues[i], @"dearchived data does not match values archived");
}
Note that there are probably better, more robust ways to archive a list of floats. I'm not looking for suggestions about that. The issue is that there are thousands of archives out there in customer land that I need to be able to read.
I've tried substituting the class _NSKeyedCoderOldStyleArray with my own to see if I can read the archive keys directly - I can get NS.count, NS.size and NS.type OK, but $0..$n, nope. Quincey Morris suggested that the actual keys may not literally be these, which is what the archive file contains. I've tried without the leading $ symbol, but with no luck. Someone may know how the keys are changed when dearchiving which might give me a possible workaround.