在iOS中创建连续的后台线程

时间:2012-06-25 12:07:01

标签: iphone objective-c ios multithreading thread-sleep

我需要创建一个仅在App处于活动模式时才有效的后台处理器。我试图制作一个我想要实现的东西,但却无法让它发挥作用。

我希望这个后台处理器在应用程序进入非活动阶段时进入休眠状态,并在应用程序进入活动模式时恢复。我已经提供了我在下面所做的工作的骨架。有人可以帮我解决这个问题。

AppDelegate.h

#import <Foundation/Foundation.h>

@class BackgroundProcessor;

@interface AppDelegate_iPhone : UIResponder<UIApplicationDelegate>{
    BackgroundProcessor* processor;
}

@property(nonatomic) BackgroundProcessor *processor;

@end

AppDelegate.m

#import "AppDelegate_iPhone.h"
#import "BackgroundProcessor.h"


@implementation AppDelegate_iPhone

@synthesize processor;

-(BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    processor = [[BackgroundProcessor alloc]init];
    [processor Start];         
    return YES;
}

-(void) applicationDidEnterBackground:(UIApplication *)application
{
    [processor Sleep];
    NSLog(@"Entered Background"); 
}

-(void) applicationDidBecomeActive:(UIApplication *)application
{
    [processor Resume];
    NSLog(@"Became Active"); 
}
@end

BackgroundProcessor.h

#import <Foundation/Foundation.h>

@interface BackgroundProcessor : NSObject
{
    NSThread* processor;
}

@property (nonatomic) NSThread *processor;

-(void) Start;
-(void) Sleep;
-(void) workloop;
-(void) Resume;
@end

BackgroundProcessor.m

#import "BackgroundProcessor.h"

@implementation BackgroundProcessor
@synthesize processor;
-(id) init
{
    self = [super init];
    if(self)
    {
        processor = [[NSThread alloc] initWithTarget:self selector:@selector(workloop) object:nil];
    }
    return self;
}

-(void) Start
{
    if(processor)
        [processor start];
}

-(void) Sleep
{
    //    [processor 
    [NSThread sleepForTimeInterval: 0.1];
}

-(void) workloop
{
    NSLog(@"Background Processor Processing ....");  
    [NSThread sleepForTimeInterval:0.1];
}

- (void) Resume
{
    NSLog(@"Background Resuming ....");  
    [NSThread sleepForTimeInterval: 0.1];
}

我无法获得工作循环以使其连续运行。 感谢有人可以帮我解决为什么背景

在Joshua Smith的建议后尝试了这个

#import "BackgroundProcessor.h"

@implementation BackgroundProcessor

-(id) init
{
    self = [super init];
    if(self)
    {
        queue = [[NSOperationQueue alloc] init];
        NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(workloop) object:nil];
        [queue addOperation:operation];
    }
    return self;
}

-(void) workloop
{

    NSLog(@"Sleeping for 10 seconds");  
    sleep(10);
    NSLog(@"Background Processor Processing ....");  
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(workloop) object:nil];
    [queue addOperation:operation];
}

@end

5 个答案:

答案 0 :(得分:4)

除非有某些特定原因,否则这必须是一个离散的线程,我建议你使用GCD或NSOperation队列来生产和消费工人。这种长期运行的线程在iOS应用程序中将成为一个真正的问题。

GCD教程:

http://www.raywenderlich.com/4295/multithreading-and-grand-central-dispatch-on-ios-for-beginners-tutorial

答案 1 :(得分:2)

我已经实现了与你描述的类似的场景。它的实现方式是在后台线程上运行连续计时器。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        notification = [[NotificationCentre alloc] init];

        notificationTimer = [NSTimer scheduledTimerWithTimeInterval:30.0 target:self selector:@selector(notificationTimerFired:) userInfo:nil repeats:YES];

        [[NSRunLoop currentRunLoop] run]; 

    });
    [self.window makeKeyAndVisible];

    return YES;
}

-(void)notificationTimerFired:(NSTimer *)theTimer {
    BOOL hasNotifications;

    if (notificationTimerActive == YES) {

        do {
            hasNotifications = [notification GetNotifications];
        } while (hasNotifications == YES);

    }

    return;

}

所以基本上当应用程序启动时,我启动重复计时器异步,然后在我的noticiationCenter类上调用我的GetNotifications方法。

答案 2 :(得分:0)

默认情况下,当您进入后台时,所有进程都将停止。可以在后台完成几个不同的过程。即使你创建了一个新线程,当你进入后台时它仍然会停止。

答案 3 :(得分:0)

来自您的评论

  

我基本上想要生成一个不断检查数据库的线程   定期将数据从我的应用程序发送到服务器。你会怎么   推荐一个理想的选择来做这样的事情。有没有   文章或代码,我可以参考,有一个解决方法   而不是产生我自己的线程?而且这个操作需要发生   仅当应用程序处于Foreground或Active模式时。

我会说你在这里使用错误的方法。当应用程序在前台更新服务器时,只需定期启动异步操作。对于这个用例,使用长期存在的后台线程是完全错误的。

答案 4 :(得分:0)

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [[NSRunLoop currentRunLoop] run];
}