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

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
4

5 に答える 5

4

これが個別のスレッドである必要がある特別な理由がない限り、GCDまたはNSOperationキューを使用して、ワーカーを生成および消費することをお勧めします。この種の長時間実行スレッドは、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

デフォルトでは、バックグラウンドに入るとすべてのプロセスが停止します。バックグラウンドで実行できるプロセスはごくわずかです。新しいスレッドを作成しても、バックグラウンドに入るとスレッドは停止します。

于 2012-06-25T12:17:46.257 に答える
0

あなたのコメントから

基本的に、アプリからサーバーにデータを送信するためにDBを定期的にチェックし続けるスレッドを生成したいと思います。このようなことをするための理想的なオプションは何をお勧めしますか。自分のスレッドを生成する代わりに回避策を用意するために、参照できる記事やコードはありますか?また、この操作は、アプリケーションがフォアグラウンドまたはアクティブモードの場合にのみ実行する必要があります。

ここでは間違ったアプローチを使用していると思います。アプリがフォアグラウンドにあるときに定期的に非同期操作を実行して、サーバーを更新します。長期間有効なバックグラウンドスレッドを使用することは、このユースケースでは明らかに間違っています。

于 2012-06-25T12:23:33.867 に答える
0
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [[NSRunLoop currentRunLoop] run];
}
于 2014-08-15T04:04:40.137 に答える