views:

279

answers:

1

I'm having an NSData object of approximately 1000kb big. Now I want to transfer this via bluetooth. This would be better if I have let's say 10 objects of 100kb. It comes to mind that I should use the -subdataWithRange: method of NSData.

I haven't really worked with NSRange. Well I know how it works, but then to read from a given location with the length: 'to end of file'... I've no idea how to do that.

Some code on how to split this into multiple 100kb NSData objects would really help me out here. (it probably involves the length method to see how many objects should be made..?)

Thank you in advance.

+2  A: 

The following piece of code does the fragmentation without copying the data:

NSData* myBlob;
NSUInteger length = [myBlob length];
NSUInteger chunkSize = 100 * 1024;
NSUInteger offset = 0;
do {
    NSUInteger thisChunkSize = length - offset > chunkSize ? chunkSize : length - offset;
    NSData* chunk = [NSData dataWithBytesNoCopy:(void*)[myBlob bytes] + offset
                                         length:thisChunkSize
                                   freeWhenDone:NO];
    offset += thisChunkSize;
    // do something with chunk
} while (offset < length);

Sidenote: I should add that the chunk objects cannot safely be used after myBlob has been released (or otherwise modified). chunk fragments point into memory owned by myBlob, so don't retain them unless you retain myBlob.

Nikolai Ruhe
I'm not completely getting that. `NSData *chunk = [NSData dataWithBytesNoCopy:[myBlob bytes] + offset length:thisChunkSize freeWhenDone:NO];` is throwing a warning of course. I don't think you can say `[myBlob bytes] + offset`. Offset has nothing to do with bytes. I don't seem to understand your logic here.
Cedric Vandendriessche
I edited the code to remove the compiler warning. The rest of the code seems right to me, though I wrote it without testing. `offset` is the amount of bytes already processed. That's why every new chunk is initialized at the beginning of the data array plus the `offset`.
Nikolai Ruhe
You're saying that the `chunk` objects point into memory owned by `myBlob`. Does this mean when I transfer chunks over bluetooth they'll be corrupted on the other side? Or do you mean that I can send them but they won't be available anymore on the sender's side after releasing `myBlob`?
Cedric Vandendriessche
It's all about your process. In this process, chunk objects would point to abandoned memory if `myBlob` would be released before the chunk object. On the receiver side, the address space and memory management of your process has no relevance.
Nikolai Ruhe
Thanks for your help, all is working fine. If I use `NSData *chunk = [NSData dataWithBytes:(void*)[myBlob bytes] + offset length:thisChunkSize];` I can release the blob. May I ask why you chose the `-dataWithBytesNoCopy:`?
Cedric Vandendriessche