Encoding UIViews take long time..
Encoding UIViews take long time..
- Subject: Encoding UIViews take long time..
- From: Gustavo Pizano <email@hidden>
- Date: Sat, 11 Dec 2010 12:52:46 +0100
Hello, this comes from a previous post i did, but IW as asking something else.
So im working with UIViews which draws an image ivar in the drawRect method., now the user manipulate the view by rotating and scaling, also the user puts many more UIViews with different image ivar each, it can repeat the image.
When saving the progress, if I have many subviews, it takes quite long time, this is what I do in teh Parent view that encode only the subviews of interest
-(NSData *)archiveItemsInScene{
NSLog(@"Loopoing Trou Items");
//First take out the Item Controll from the scene if is vissible
if([bc_itemControll superview])[self removeItemControl];
//Now loop trou the items in the scene
//Creating the acchiver
NSKeyedArchiver *archiver;
NSMutableData * data = [NSMutableData data];
archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
NSArray * subViews = [bc_itemsView subviews];
NSMutableDictionary * itemsDic = [NSMutableDictionary dictionary];
CGFloat deltaP = 0.4/[subViews count];
for(UIView * actualItem in subViews){
[itemsDic setObject:actualItem forKey:[NSString stringWithFormat:@"BCItem-%i",[subViews indexOfObject:actualItem]]];
[bc_myController performSelectorOnMainThread:@selector(updateSaveRestoreProgressMenuBy:) withObject:[NSNumber numberWithFloat:deltaP] waitUntilDone:NO];
}
//[archiver encodeObject:actualItem forKey:[NSString stringWithFormat:@"BCItem-%i",[subViews indexOfObject:actualItem]]];
[archiver encodeObject:itemsDic forKey:@"BCItemsInSceneKey"];
[archiver encodeObject:bc_bgImageview.image forKey:@"BCSceneBackgroundKey"];
[archiver finishEncoding];
[archiver release];
[bc_myController performSelectorOnMainThread:@selector(updateSaveRestoreProgressMenuBy:) withObject:[NSNumber numberWithFloat:0.1] waitUntilDone:NO];
bc_sceneHasChanges = NO;
return data;
}
and this is the encodeWithCoder method of each BCItemView subview that is encoded.
#pragma mark -
#pragma mark NSCoding Protocol Methods
-(void)encodeWithCoder:(NSCoder *)aCoder{
[super encodeWithCoder:aCoder];
//Serializing the image Ref
CFMutableDataRef url = CFDataCreateMutable(kCFAllocatorDefault, 0);
CFStringRef type = kUTTypePNG;
size_t count = 1;
CFDictionaryRef options = NULL;
CGImageDestinationRef dest = CGImageDestinationCreateWithData(url, type, count, options);
CGImageDestinationAddImage(dest, bc_itemImage, NULL);
CGImageDestinationFinalize(dest);
//Encodin teh image
NSData * data = (NSData *)url;
[aCoder encodeObject:data forKey:@"BCItemImageDataKeyName"];
[aCoder encodeObject:[NSNumber numberWithBool:bc_itemIsLocked] forKey:@"BCItemLockedKey"];
//Release the dest
CFRelease(dest);
CFRelease(url);
}
So I serialize the ivar of the image, and the ivars that I really need to keep, some booleans and no more.
the
-(NSData *)archiveItemsInScene method is executed in a background thread, then when that method finish I post a notification to the caller so it will enable the menu buttons once again... something like this:
-(void)saveProgress{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDirectory = [arrayPaths objectAtIndex:0];
NSString * thumDirectory = [arrayPaths objectAtIndex:0];
BOOL dir;
NSError * error, * error2;
if(![[NSFileManager defaultManager] fileExistsAtPath:[docDirectory stringByAppendingFormat:@"/Progress/"] isDirectory:&dir]){
NSLog(@"It doesn't exist");
[[NSFileManager defaultManager] createDirectoryAtPath:[docDirectory stringByAppendingFormat:@"/Progress/"]
withIntermediateDirectories:YES attributes:nil error:&error];
[[NSFileManager defaultManager] createDirectoryAtPath:[thumDirectory stringByAppendingFormat:@"/Thumbnails/"]
withIntermediateDirectories:YES attributes:nil error:&error2];
}
//Creating the thum is alwasy gonna be slower than encoding the items... so i fired this thread first
self.bc_creationName = progressToLoad != nil ? progressToLoad:[[NSDate date] description];
[self performSelectorInBackground:@selector(createAndSaveThumbImage:) withObject:docDirectory];
//[self createAndSaveThumbImage:docDirectory];
//Now i need to save this under the thumbs
NSLog(@"Saving Items in Scene");
//locating app sandbox directory
NSData * dataOfItems = [(BCSceneView *)self.view archiveItemsInScene];
NSLog(@"Finishin Saving");
//Now saving to the app sandbox
NSString *filePath = [docDirectory stringByAppendingString:[NSString stringWithFormat:@"/Progress/%@.bc",bc_creationName]];
BOOL okSaved = [dataOfItems writeToFile:filePath atomically:YES];
[self performSelectorOnMainThread:@selector(updateSaveRestoreProgressMenuBy:) withObject:[NSNumber numberWithFloat:0.1] waitUntilDone:NO];
NSLog(@"Data Saved %i",okSaved);
[(BCSceneView*)self.view setBc_sceneHasChanges:NO];
self.progressToLoad = bc_creationName;
[self performSelectorOnMainThread:@selector(updateSaveRestoreProgressMenuBy:) withObject:[NSNumber numberWithFloat:1.0] waitUntilDone:NO];
[[NSNotificationCenter defaultCenter] postNotificationName:@"BCFinishSaving" object:nil];
[pool drain];
}
saveProgress is called from a menu and using the NSThread class method detachThread.... So here in this method I run another background thread to make the thumbnail, and make the saving and thumbnail operations parallel, this saved me some seconds :D.
Any way to improve even more performance?, when I have many many BCItemView on the scene, (around 120+), it takes like 10 seconds to save. :S
Thanks
Gustavo
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden