Friday, November 22, 2013

Online Session Code for Big Objects (Plus a Warning)

During Chapter 9 of extra iPhone Development, we wrote a usual of classes to facilitate mimicked the behavior of GameKit's peer-to-peer connectivity, but representing regular interact contacts (GameKit's single factory with BlueTooth and native interact connections). Basically, we wrote a taste to facilitate lets you propel and receive something to facilitate can be packaged into an demand of NSData. Since it's relatively trivial to apply NSCoding representing for the most part classes, this way leave-taking objects amid two iOS apps (or an iOS and a Mac app) becomes pretty unproblematic. You don't own to census representing the data, or uneasiness around chunking improbable the data. You truly nominate a method call and pass an NSData demand to propel data, and followed by apply a delegate method representing receiving data back from the other top. Life is respectable, justification?

Hmm...

Maybe not. There's a pretty large limitation in the book's implementation. That implementation, designed representing leave-taking tiny packets of data (TicTacToe game moves), held in reserve everything in recall. If you try to propel a respectable size image to the other connection, likely you'd run improbable of recall practically quickly.

A while back, I faced exactly to facilitate post. For a kiosk app to facilitate MartianCraft was script representing a client, I considered necessary to propel fat images shot with a DSLR camera from a Mac Cocoa encode to an iPad encode and furthermore considered necessary to propel pictures taken with the iPad's camera back to the Mac Cocoa app. These images, compressed, ranged from around solitary to around five megs. I grabbed the OnlineSession taste from extra, figuring I had the interact code basically complete, and watched my relevance make for down in a glow of… well… not glory, that's representing convinced. Not single did the iPad run improbable of recall, it ran improbable of recall FAST… much quicker than I estimated. Even conveyance the lesser iPad camera images often caused low-memory crashes.

There were two basic problems with the OnlineSession taste what time you try to consume it representing conveyance better volumes of data. First, as I held, was to facilitate it relied single on bodily recall. Given to facilitate the bodily limitations of the real thing iPad, this was problematic. But at hand was a further, much larger glitch.

The support matter was to facilitate at some point in the process of chunking up the data to propel, the code held in reserve making superfluous copies of the data. Put simply, I made a n00b gaffe. The gaffe didn't blow the TicTacToe relevance since the game moves would effortlessly fit into the propel storage area, but it's a gaffe I've made or and absolutely should've branded better.

So, come again?, specifically, was this gaffe, you ask?

Using NSData's regular convenience constructor dataWithBytes:Extent: What time creating the modern NSData demand to salt away the portion of the image to facilitate won't fit into the propel storage area. If you read the explanation of dataWithBytes:Extent:, it very visibly says to facilitate it makes a ape of the data you provide. So, all stage a packet was sent, the code would create a modern NSData demand to foothold the remainder to facilitate wouldn't fit in the storage area, and it would ape all the residual unsent data representing all packet. Ouch.

So, as a clean illustration, if we were conveyance a 5 meg image, and the propel storage area was usual to 128k, the code would nominate a 4.825 meg ape in the same way as the chief packet was sent, followed by a 4.75 meg ape in the same way as the support packet was sent, a 4.265 meg ape in the same way as the third packet, and so on. After all packet, a further a little lesser ape of the data was made. A descending progress to facilitate would dine up recall fast.

After a lot in life of swearing next to myself, I made a quantity of modifications to the taste to look after two things.

First, I switched to using NSData's dataWithBytes:NoCopy:Extent:, which uses the provided data in place exclusive of making a ape. This held in reserve the recall footprint a lot in life lesser. During a quantity of instances, since the DSLR images were so fat and our app considered necessary to propel so many, I still thump recall problems. So, the support issue I did was to add filesystem caching of the outbound queue so to facilitate all the encoded objects waiting to be sent didn't own to fit in recall representing the relevance to function appropriately.

The modern version of the taste functions exactly as the solitary from the hardback, so you must be able to truly drop-in return the OnlineSession from Chapter 9 with this solitary exclusive of making several changes to your relevance code.

You can download the modern version justification now.

No comments:

Post a Comment