4

我需要创建一个仅在应用程序处于活动模式时才工作的后台处理器。我试图对我想要实现的目标做出一个骨架,但无法让它发挥作用。

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

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

背景处理器.h

#import <Foundation/Foundation.h>

@interface BackgroundProcessor : NSObject
{
    NSThread* processor;
}

@property (nonatomic) NSThread *processor;

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

背景处理器.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];
}

我无法让工作循环让它持续运行。感谢是否有人可以帮助我解决为什么背景

在约书亚史密斯的建议之后尝试了这个

#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
4

5 回答 5

4

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

GCD教程:

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

于 2012-06-25T12:13:14.203 回答
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 方法。

于 2012-06-25T13:03:58.843 回答
0
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [[NSRunLoop currentRunLoop] run];
}
于 2014-08-15T04:04:40.137 回答
0

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

于 2012-06-25T12:17:46.257 回答
0

从你的评论

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

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

于 2012-06-25T12:23:33.867 回答