On May 27, 2010, at 4:21 AM, Philip Vallone wrote:

> I am passing different types of data to NSData (NSString, NSArray, UIImage).  
> I am trying to find out what kind of data t is so I know how to handle the 
> NSData when I receive it.

NSData is just a byte sequence.  It doesn't have any knowledge about the 
semantic meaning of those bytes.

I'm not even sure what you mean by "passing different types of data to NSData". 
 You don't pass strings, arrays, or images to NSData.  You can ask some of 
those objects for data, but that's not the same thing.


>       NSString *somedata = [[NSString alloc] initWithString:@"Some string"];  

The above is a warning sign.  I see it a lot with new Cocoa programmers.  The 
expression

        @"Some string"

is already a full-fledged string object.  You can send it messages and 
everything.  There's no reason to "turn it into a string object" or "make a 
string object from it" or anything like that.  Creating a new string from it, 
as you've done with +alloc and -initWithString: accomplishes nothing but a bit 
of waste.

I only point it out because it indicates a weakness in your understanding of 
the language and framework.

Also, calling a string "somedata" is just going to confuse you and anybody else 
reading your code.  A string object is not a data object.

>       NSData * set = [NSKeyedArchiver archivedDataWithRootObject:[somedata 
> dataUsingEncoding:NSASCIIStringEncoding]];

I don't think this is doing what you want.  The expression "[somedata 
dataUsingEncoding:NSASCIIStringEncoding]" asks the string to create a byte 
sequence by encoding its contents into ASCII.  It puts the byte sequence into a 
data object and returns it to you.  Once again, the data object knows nothing 
about the semantics of the byte sequence.  You can't query it and ask, "were 
you originally a string?"  It doesn't have the slightest clue.

Then, you create another data object by key-archiving the data object with the 
ASCII byte sequence.  That second data object also doesn't know that it's a 
keyed archive containing a data object (which happens to contain an ASCII byte 
sequence of a string).

However, it does have internal structure so that an NSKeyedUnarchiver can 
rediscover that it was a data object.  But that still doesn't imbue the 
unarchived data object with knowledge that it originally came from a string.

The question is, why did you ASCII-encode the string into a data object if you 
were then going to archive that data object into another data object.  I think 
you probably want to simply archive the string, directly:

        NSData* set = [NSKeyedArchiver archivedDataWithRootObject:somedata];

Again, calling a data object a "set" is just confusing.

>       NSData * unset = [NSKeyedUnarchiver unarchiveObjectWithData:set];

With your original code, unset would now point to a data object which contains 
the ASCII byte sequence obtained from the string.  Still, though, this data 
object has no way of knowing that its contents are ASCII-encoded characters or 
that it came from a string.

>       NSLog(@"Class Type %@", [unset isKindOfClass:[NSKeyedUnarchiver 
> class]]);

Alexander has already pointed out the problems with this line.  But, more 
fundamentally, there's no amount of querying of the unarchived data object that 
will reveal what it once was.  It doesn't know.  You'll only learn that it is a 
data object.

If you had originally archived the string object instead of a data object 
obtained by asking the string to encode itself, then you would have gotten back 
an equivalent string object.  You could usefully ask that string object about 
its class using -isKindOfClass:.

To summarize, perhaps this does what you're looking for:

        NSString* somestring = @"Some string";
        NSData* archive = [NSKeyedArchiver 
archivedDataWithRootObject:somestring];
        // ... later ...
        id obj = [NSKeyedUnarchiver unarchiveObjectWithData:archive];
        if ([obj isKindOfClass:[NSString class]])
                // ... use 'obj' as a string
        else if ([obj isKindOfClass:[NSArray class]])
                // ... use 'obj' as an array
        // ... etc. ...

(Note that I don't release somestring because I don't own it, by the memory 
management rules.  You were correct to release yours, though, since your code 
did own its.)

Regards,
Ken

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to