Hello.
My application is saving some data, and it takes a while to do it, it can be 1
second to 10 sec around.. Im doing some image processing, The thing is..
I send the saving operation in another thread using the NSThread +
detachNewThreadSelector:toTarget:withObject: method, and in the main thread I
update a UIActivityIndicator, and stop it when I receive the
NSThreadWillExitNotification. The problem is that when it takes long to save,
it may seem the app is somehow stuck, even the spinning indicator is running.
I wanted to change the ActivityIndicator to a progressview, but then I can't
make it work because the saving process not on the main thread, i think..
correct me if Im wrong, Im not so much familiar with multithreaded apps.
As for the saving process, what I do is the following.
I have a Parent view which contains subviews, these subviews are drawing
images. The user can modify this images, (scale and rotate), so when I save i
encode these views so it will save the view's transform, and then I archive
the data I encoded for all these subviews.
Also at the same time Im taking a screenshot to create a thumbnail image of the
"progress", so the user can reload it anytime.
the subviews are one Class Called ItemView, and these is what I did in the
encoding methods
#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"];
//Release the dest
CFRelease(dest);
CFRelease(url);
}
-(id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
bc_isSelected = bc_isInBox = bc_willMoveFromBox = NO;
//Deserializing the Image
NSData * data = [aDecoder
decodeObjectForKey:@"BCItemImageDataKeyName"];
CFDataRef imgData = (CFDataRef)data;
CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData
(imgData);
bc_itemImage = CGImageCreateWithPNGDataProvider(imgDataProvider, NULL,
true, kCGRenderingIntentDefault);
return self;
}
And this is the method that is called when excecting the NSThread
detachNewThreadSelector method
-(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];
}
//Im gonna create a thumbView of the current progress,
UIImage * currentProgressImage = [self screenShotOfSceneView];
CGFloat thumbWidth, thumbHeiht;
if([currentProgressImage size].height > [currentProgressImage
size].width){
thumbHeiht = 150.0f;
thumbWidth = 112.5;
}
else {
thumbHeiht = 112.5;
thumbWidth = 150.5;
}
UIImage * thumb = [UIImage imageWithImage:currentProgressImage
scaledToSize:CGSizeMake(thumbWidth, thumbHeiht)];
//Archivign the thumbnails
NSKeyedArchiver *archiver;
NSMutableData * dataThumb = [NSMutableData data];
archiver = [[NSKeyedArchiver alloc]
initForWritingWithMutableData:dataThumb];
[archiver encodeObject:thumb forKey:@"BCProgressThumbnail"];
[archiver finishEncoding];
[archiver release];
//[bc_creationName release];
self.bc_creationName = progressToLoad != nil ? progressToLoad:[[NSDate
date] description];
NSString *thumbPath = [docDirectory stringByAppendingString:[NSString
stringWithFormat:@"/Thumbnails/%[email protected]",bc_creationName]];
BOOL okSavedThumb = [dataThumb writeToFile:thumbPath atomically:YES];
NSLog(@"Thumb Saved %i",okSavedThumb);
NSLog(@"Saving Items in Scene");
//locating app sandbox directory
NSData * dataOfItems = [(BCSceneView *)self.view archiveItemsInScene];
// The scene loops on all the items subviews and encodes them
NSLog(@"Finishin Saving");
//Now saving
//Getting the date
NSString *filePath = [docDirectory stringByAppendingString:[NSString
stringWithFormat:@"/Progress/%[email protected]",bc_creationName]];
BOOL okSaved = [dataOfItems writeToFile:filePath atomically:YES];
NSLog(@"Data Saved %i",okSaved);
[(BCSceneView*)self.view setBc_sceneHasChanges:NO];
self.progressToLoad = bc_creationName;
[pool drain];
}
So basically Im saving and creating the thumbnail in that thread, I think this
can be done in 2 different threads, one that saves and that that creates the
thumbnail, right?, any considerations to take in mind?, how can i improve
saving time?
Thanks
Gustavo
PS:The decoding process is very fast., it takes no more than 2 seconds.
_______________________________________________
Cocoa-dev mailing list ([email protected])
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]