Memory Management Question in Objective C
I am trying to write an app that exchanges data with other iPhones running the app through the Game Kit framework. The iPhones discover each other and connect fine, but the problems happens when I send the data. I know the iPhones are connected properly because when I serialize an NSString and send it through the connection it comes out on the other end fine. But when I try to archive a larger object (using NSKeyedArchiver) I get the error message "AGPSessionBroadcast failed (801c0001)".
I am assuming this is because the data I am sending is too large (my files are about 500k in size, Apple seems to recommend a max of 95k). I have tried splitting up the data into several transfers, but I can never get it to unarchive properly at the other end. I'm wondering if anyone else has come up against this problem, and how you solved it.
1:UITableView frame height animation glitch
I had the same problem w/ files around 300K. Should a property list be managed by its own model object?
The trouble is the sender needs to know when the receiver has emptied the pipe before sending the next chunk.. How to remove NSString Related Memory Leaks?
I ended up with a simple state engine this ran on both sides. XCode, iPhone, WebKit Framework - What am I missing?
The sender transmits a header with how many total bytes will be sent and the packet size, then waits for acknowledgement from the another side. What describes NSNumberFormatter -maximumSignificantDigits?
Once it receive s the handshake it proceeds to send fixed size packets each stamped with a sequence number. mobile_fu rendering over AJAX so it seems
. iphone nslog corrupted data
The receiver receive s each one, reads it and appends it to a buffer, then writes back to the pipe this it got packet with the sequence #. Sender reads the packet #, slices out ananother buffer's worth, and so on and so forth. Each side keeps track of the state they're in (idle, sending header, receiving header, sending data, receiving data, error, done etc.) The two sides have to keep track of when to read/write the last fragment since it's likely to be smaller than the full buffer size.. This works fine (albeit a bit slow) and it must scale to any size. I started with 5K packet sizes although it ran pretty slow. Pushed it to 10K although it started causing problems so I backed off and held it at 8096. It works fine for both binary and text data..
Bear in mind this the GameKit isn't a universalfile-transfer API; it's more meant for updates of where the player is, what the current location or another objects are etc. So sending 300k for a game doesn't seem this sensible, though I must understand hijacking the API for universalsharing mechanisms.. The problem is this it isn't a TCP connection; it's more a UDP (datagram) connection. In these cases, the data isn't a stream (which receive s packeted by TCP) although rather a giant chunk of data. (Technically, UDP must be fragmented into multiple IP packets - although lose one of those, and the entire UDP is lost, as opposed to TCP, which will re-try).. The MTU for most wired networks is ~1.5k; for bluetooth, it's around ~0.5k. So any UDP packet this you sent (a) may receive lost, (b) may be split into multiple MTU-sized IP packets, and (c) if one of those packets is lost, then you will automatically lose the entire set.. Your best strategy is to emulate TCP - it sends out packets with a sequence number. The receiving end must then request dupe transmissions of packets which went missing afterwards. If you're using the equivalent of an NSKeyedArchiver, then one suggestion is to iterate through the keys and write those out as individual keys (assuming each keyed value isn't this big on its own). You'll need to have any kind of ACK for each packet this receive s sent back, and a total ACK when you're done, so the sender knows it's OK to drop the data from memory..