I'm a new in iOS. I'm working on the app needs to run a task for getting data from Server in the background thread as i don't want to lock the UI in main thread. This task will take a long time, I tried using the NSTimer but it is still lock the UI. My task is to check new messages in Chat screen, I need to call this task every 5s. If I use NSTimer, when input text , the text seems to freeze a moment while this task is performing. Is there any way to process this task without lock UI. Please give me some advices. Thanks so much.
我是iOS的新手。我正在开发的应用程序需要运行一个任务,从后台线程的服务器获取数据,因为我不想把UI锁在主线程中。这个任务将花费很长时间,我尝试使用NSTimer,但它仍然锁定UI。我的任务是在聊天屏幕上检查新消息,我需要每5秒调用这个任务。如果我使用NSTimer,当输入文本时,文本在执行任务时似乎会冻结片刻。是否有任何方法可以在没有锁定UI的情况下处理此任务。请给我一些建议。非常感谢。
== UPDATE CODE ==
= = = =更新代码
- (void)performBackgroundTask
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//Do background work
if([[NSUserDefaults standardUserDefaults] boolForKey:@"LoggedIn"]) {
NSDictionary * userDictionary = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"SessionDictionary"];
NSString *authenKey= [userDictionary valueForKey:@"authToken"];
NSString* limit = @"1000";
[[LSDataManager sharedDataManager] getLatestMessagesWithAuthKey:authenKey andLimit:limit withBlock:^ (NSDictionary* responseDict)
{
if (responseDict) {
[self loadDataFromServer:responseDict];
NSArray* lastMessageArray= nil;
//filter message data
if (self.MessagesArray.count >0) {
if (!self.isSeller) {
lastMessageArray = [self filterMessageData:self.MessagesArray withProductID:self.productID withSellerID:self.receiverID withBuyerID:self.senderID];
}
else
{
lastMessageArray = [self filterMessageData:self.MessagesArray withProductID:self.productID withSellerID:self.senderID withBuyerID:self.receiverID];
}
NSLog(@"filter array %@",lastMessageArray);
if([lastMessageArray count] >0){
//[self loadMessages:lastMessageArray];
if (self.TempdataSource == nil) {
self.TempdataSource = [NSMutableArray array];
}
else
{
[self.TempdataSource removeAllObjects];
}
self.TempdataSource = [[[ContentManager sharedManager] generateConversation:lastMessageArray withSenderID:self.senderID] mutableCopy];
}
}
}
}];
}
dispatch_async(dispatch_get_main_queue(), ^{
//Update UI
//compare 2 arrays
if ([self.TempdataSource count] == [self.dataSource count]) {
NSLog(@"both are same");
}
else{
NSLog(@"both are different");
self.dataSource = [self.TempdataSource mutableCopy];
[self refreshMessages];
}
});
});
}
2 个解决方案
#1
34
Scheduling the task using an NSTimer is indeed the right way to go. You just need to make sure you're running your heavy non-UI code on a background thread. Here's an example
使用NSTimer调度任务确实是正确的方法。您只需要确保在后台线程上运行大量非ui代码。这里有一个例子
- (void)viewDidLoad {
[super viewDidLoad];
[self startTimedTask];
}
- (void)startTimedTask
{
NSTimer *fiveSecondTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(performBackgroundTask) userInfo:nil repeats:YES];
}
- (void)performBackgroundTask
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//Do background work
dispatch_async(dispatch_get_main_queue(), ^{
//Update UI
});
});
}
#2
14
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Thread
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
});
});
Try this
试试这个
#1
34
Scheduling the task using an NSTimer is indeed the right way to go. You just need to make sure you're running your heavy non-UI code on a background thread. Here's an example
使用NSTimer调度任务确实是正确的方法。您只需要确保在后台线程上运行大量非ui代码。这里有一个例子
- (void)viewDidLoad {
[super viewDidLoad];
[self startTimedTask];
}
- (void)startTimedTask
{
NSTimer *fiveSecondTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(performBackgroundTask) userInfo:nil repeats:YES];
}
- (void)performBackgroundTask
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//Do background work
dispatch_async(dispatch_get_main_queue(), ^{
//Update UI
});
});
}
#2
14
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Thread
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
});
});
Try this
试试这个