How are you doing, all?

I found a interesting one with the NSValue class, and would like to ask a couple of questions.

First, I would like to put data from a callback function to an global or a singleton NSArray. The data structure which holds the all the data is :

typedef struct simpleDescription {
   int dataType;
   int dataKind;
   unsigned char uuid;
} simpleDescription;

typedef struct complexType {
   uint8_t *data;
   int dataSize;
   int year;
simpleDescription *dataDesc;
   int tag;
} complexType;

So, the data to queue is in complexType. It contains chunk of data of which is is dataSize. While the length of the data is various, but the length of dataDesc is fixed. ( It will not point to an array of simpleDescription, but one simpleDescription instance. )

I also made another structure, which is the same to the complexType - data,

typedef struct complexTypeConveyer
{
   int dataSize;
   int year;
simpleDescription *dataDesc;
   int tag;
} complexTypeConveyer;

It is for converting them using [NSValue valueWithBytes: objCType:] easily.

So, the queuing process is :

- (IBAction)encode:(id)sender
{
   // Setup complexType
simpleDescription *dataDesc = (simpleDescription *)malloc( sizeof( simpleDescription ) );
   dataDesc->dataType ='JaPA';
   dataDesc->dataKind = 'CUST';
   dataDesc->uuid = 0x01;
uint8_t *data = (uint8_t *)malloc( 512 );
   memset( data, 0x0E, 512 );
   complexType dataSet;
dataSet.data = data;
   dataSet.dataSize = 512;
   dataSet.year = 1980;
   dataSet.dataDesc = dataDesc;
   dataSet.tag = 1;
[self printComplexType:&dataSet toView:lefTextView]; // Move to the conveyer
   complexTypeConveyer theConveyer;
   theConveyer.dataSize = dataSet.dataSize;
   theConveyer.year = dataSet.year;
   theConveyer.dataDesc = dataSet.dataDesc;
   theConveyer.tag = dataSet.tag;
NSValue *aValue = [NSValue valueWithBytes:&theConveyer objCType:@encode(complexTypeConveyer)];
   NSLog( @"aValue retainCount = %d", [aValue retainCount] );
NSData *theDataToConvey = [NSData dataWithBytes:dataSet.data length:dataSet.dataSize]; NSDictionary *conveyDictionary = [NSDictionary dictionaryWithObjectsAndKeys:aValue, @"complexTypeConveyer", theDataToConvey, @"dataToConvey", nil]; mDataQueue = [NSArray arrayWithObject:conveyDictionary];
   NSLog( @"aValue retainCount = %d", [aValue retainCount] );
//bzero( data, 512);
   free( data );
//bzero( dataDesc, sizeof( simpleDescription ) );
   free( dataDesc );
[self recover];
}

As you can see, it will retrieve the queued data in mDataQueue in its - recover message.

- (void)recover
{
   //////////////////////
   // Recover the data
complexTypeConveyer recoveredConveyedType; NSDictionary *recoveredDictionary = (NSDictionary *)[mDataQueue objectAtIndex:0]; NSValue *recoveredValue = (NSValue *)[recoveredDictionary objectForKey:@"complexTypeConveyer"]; NSData *recoveredData = (NSData *)[recoveredDictionary objectForKey:@"datatoConvey"]; [recoveredValue getValue:&recoveredConveyedType]; uint8_t *recoveredInnerData = (uint8_t *)malloc( recoveredConveyedType.dataSize ); [recoveredData getBytes:recoveredInnerData length:recoveredConveyedType.dataSize]; // Now restore the complex type
   complexType recoveredType;
   recoveredType.data = recoveredInnerData;
   recoveredType.dataSize = recoveredConveyedType.dataSize;
   recoveredType.year = recoveredConveyedType.year;
   recoveredType.dataDesc = recoveredConveyedType.dataDesc;
   recoveredType.tag = recoveredConveyedType.tag;
[self printComplexType:&recoveredType toView:rightextView]; free( recoveredType.data );
   free( recoveredType.dataDesc );
}

There is a reason I didn't include the "data" in the NSValue using the valueWithBytes: objCType:. When it retrieves the value from the mDataQueue, the content doesn't seem to be maintained. Also, the document is somewhat ambiguous.

"An NSValue object is a simple container for a single C or Objectie-C data item. It can hold any of the scalar types such as int, float, and char, as welll as pointers, structures, and object ids. "
-- from "Number and Value Programming Topics for Cocoa"

It sounds like that it only transforms pointers in a structure, not the target content pointed by the pointers. So, as a test I put the dataDesc just as a pointer to the structure. ( In the source above, dataDesc is declared as :

(case 1)
simpleDescription *dataDesc

But I also tried :

(case 2)
simpleDescription dataDesc

And assigned its address to the field of the complexType.
The purpose of case 2 is to see if the retrieved data in the recover function is invalid, because it is declared statically in the "encode" action handler. ( I thought it should be invalid. However, somehow it was maintained. This is one of the question I would like to ask. How it can be maintained although it is out of the scope? From recover message's point of view, it is declared in the stack area of other message! )

There are couple of interesting things, anyway.

1. Whether the dataDesc is statically declared or not, although it is freed in the end of the "encode" action handler, it is still maintained and could be accessed from another message, "recover". And with the Memory browser, I could confirm that the memory content was still there. Why is it so? Does the NSData or NSArray just retains them?

2. However, when I intentionally bzero it, the content is nullified, and the recover message sees the content as zeros. So, it is not caches in the NSArray. It seems to me that it just uses by referencing.

3. Should they be also freed in the recover function although it is done so in the "encode" action handler?

4. Should the dataDesc also be transformed separately as the data is?

5. for the data, I used dataWithBytes: length: thinking that it will copy the contents, instead of just referencing the original. However, it turns out that it just references it. I figured that out by bzeroing the original, and how it is seen in the recover function. There is another message, dataWithBytesNoCopy:length:. It made me think that the dataWithBytes:length copies, while the dataWithBytesNoCopy:length just references it. The explanation on the dataWithBytes:length: is :

"The number of bytes to 'copy' from bytes."

But as I described, it doesn't seem to copy.

Can anyone help me?

Thank you.
JongAm Park

_______________________________________________

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 [EMAIL PROTECTED]

Reply via email to