Ken & Alexander,

Thank you so much for your help. Your explanations are extremely helpful. 

Best regards, 

Phil

On May 27, 2010, at 6:36 AM, Ken Thomases <[email protected]> wrote:

> 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 ([email protected])

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 [email protected]

Reply via email to