您的位置:首页 > 理论基础 > 计算机网络

iphone基于网络的客户端开发技巧——后台上传

2012-03-12 23:31 381 查看
from: http://blog.sina.com.cn/s/blog_4cd8dd130100t5cm.html
这里说的后台上传当然不是真的后台上传,只是在开启程序的情况下不影响操作的上传。

基本的思想就是开启一个线程,不断的处理上传操作。这里用队列比较方便一些。

主要做以下几步:

第一步:实现一个自定义类,继承NSObject

@interface MinroadOperation : NSObject {

NSOperationQueue *operationQueue;

}

- (void)addOperation:(NSDictionary *)_dic;

- (void)reStartOperation:(NSDictionary *)_dic;

@property (retain,nonatomic) NSOperationQueue *operationQueue;

@end


@implementation MinroadOperation

@synthesize operationQueue;

- (id)init

{

self = [super init];

if (self) {

self.operationQueue = [[NSOperationQueue alloc] init];

[self.operationQueue setMaxConcurrentOperationCount:2];//设置同时进行的线程数量,建议为2。

}

return self;

}


- (void)addOperation:(NSDictionary
*)_dic

{

//保存上传列表到nsuserdefaults

NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];

if ([userDefault valueForKey:@"upload"] == nil) {

NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSMutableArray arrayWithObject:_dic],@"upload",nil];

[userDefault registerDefaults:dic];

[userDefault synchronize];

}

else {

NSArray *array = [userDefault valueForKey:@"upload"];

NSMutableArray *arr = [[NSMutableArray alloc] initWithArray:array];

[arr addObject:_dic];

[userDefault setObject:arr forKey:@"upload"];

[arr release];

[userDefault synchronize];

}


//添加到队列

NSInvocationOperation* theOp = [[NSInvocationOperation alloc] initWithTarget:self

selector:@selector(myTaskMethod:) object:_dic];

[self.operationQueue addOperation:theOp];

[theOp release];

//更新UI

}

- (void)reStartOperation:(NSDictionary *)_dic

{

//从userdefaults读取数据,并添加到队列

NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];

NSArray *array = [userDefault valueForKey:@"upload"];

NSMutableArray *arr = [[NSMutableArray alloc] initWithArray:array];

int i = (int)[arr indexOfObject:_dic];

if (i == NSNotFound) {

return;

}

NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:[arr objectAtIndex:i]];

[dic setValue:[NSNumber numberWithInt:0] forKey:@"state"];//0 等待上传 1 上传中 2 失败

[arr replaceObjectAtIndex:i withObject:dic];

[userDefault setValue:arr forKey:@"upload"];

[userDefault synchronize];

NSInvocationOperation* theOp = [[NSInvocationOperation alloc] initWithTarget:self

selector:@selector(myTaskMethod:) object:dic];

[self.operationQueue addOperation:theOp];

[theOp release];

//更新UI

}

- (void)myTaskMethod:(id)_obj

{

//实现上传方法

//成功调用

[self performSelectorOnMainThread:@selector(taskMethodDidFinish:) withObject:nil waitUntilDone:YES];

//失败调用

[self performSelectorOnMainThread:@selector(taskMethodDidFailed:) withObject:nil waitUntilDone:YES];

}

- (void)taskMethodDidFailed:(id)_obj

{

//失败的任务更改状态之后保存

NSDictionary *tdic = [_obj retain];

NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:tdic];

[dic setValue:[NSNumber numberWithInt:1] forKey:@"state"];

NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];

NSArray *array = [userDefault valueForKey:@"upload"];

NSMutableArray *arr = [[NSMutableArray alloc] initWithArray:array];

int _index = (int)[arr indexOfObject:dic];

if (_index != NSNotFound) {

NSMutableDictionary *tmp = [NSMutableDictionary dictionaryWithDictionary:[arr objectAtIndex:_index]];

[tmp setValue:[NSNumber numberWithInt:2] forKey:@"state"];//0 等待上传 1 上传中 2 失败

[arr replaceObjectAtIndex:_index withObject:tmp];

}

[userDefault setObject:arr forKey:@"upload"];

[arr release];

[userDefault synchronize];

//更新UI

}

- (void)taskMethodDidFinish:(id)_obj

{

//成功的任务从userdefaults中删除

NSDictionary *tdic = [_obj retain];

NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:tdic];

[dic setValue:[NSNumber numberWithInt:1] forKey:@"state"];

NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];

NSArray *array = [userDefault valueForKey:@"upload"];

NSMutableArray *arr = [[NSMutableArray alloc] initWithArray:array];

int _index = (int)[arr indexOfObject:dic];

if (_index != NSNotFound) {

[arr removeObjectAtIndex:_index];

}

[userDefault setObject:arr forKey:@"upload"];

[arr release];

[userDefault synchronize];

//更新UI

}

- (void)dealloc

{

[operationQueue release];

[super dealloc];

}

@end


第二步:在appdelegate中初始化一个MinroadOperation对象,添加的时候用addOperation(),重新开始的时候用reStartOperation()。

第三步:在程序重新开启的时候启动队列。同时有一点不确认,就是从后台返回貌似队列会继续进行,也就是说进入后台的时候队列处在等待状态。

需要注意的几点:

1. NSInvocationOperation的cancel方法只是设置一个标识,在进入队列的时候判断是否为true,从而判断是否进行。如果想取消NSInvocationOperation,可以尝试继承它。

2.避免无限重试。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: