1

私はfileeventapiを使用してフォルダーを監視するデスクトップアプリケーションに取り組んでいるので、基本的にこれは私のコードです:

#import "PNAppDelegate.h"

void callback(
              ConstFSEventStreamRef streamRef,
              void *clientCallBackInfo,
              size_t numEvents,
              void *eventPaths,
              const FSEventStreamEventFlags eventFlags[],
              const FSEventStreamEventId eventIds[]) 
{
    [(__bridge PNAppDelegate *)clientCallBackInfo reloadStatus];

};

@implementation PNAppDelegate

@synthesize window = _window;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    NSArray *pathsToWatch = [NSArray arrayWithObject: @"/Users/romainpouclet/Projects/foo"];

    void *appPointer = (__bridge void *)self;
    FSEventStreamContext context = {0, appPointer, NULL, NULL, NULL};

    FSEventStreamRef stream;
    CFAbsoluteTime latency = 3.0;

    stream = FSEventStreamCreate(NULL, 
                                 &callback, 
                                 &context, 
                                 (__bridge CFArrayRef) pathsToWatch, 
                                 kFSEventStreamEventIdSinceNow, 
                                 latency, 
                                 kFSEventStreamCreateFlagNone);

    NSLog(@"Schedule with run loop");
    FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
    FSEventStreamStart(stream);
    [self reloadStatus];
}

-(void)reloadStatus
{

}

@end

問題ありません。これと同じくらい単純なPOCの場合はかなりうまく機能しますが、少し醜い感じがします(おそらく、Objective-CとCの混合にはあまり慣れていません)。だからここに私の質問があります:

  • コールバックはどこで宣言すればよいですか?それがそこで機能したという理由だけで、私のファイルの先頭にそれがあるのは奇妙に感じます。
  • コールバックの代わりに、ある種の@selectorベースのアプローチを使用することは可能ですか?(私は彼らが安心していると思います:D)

御時間ありがとうございます !

4

2 に答える 2

2

コールバック宣言をPNAppDelegate.hまたは独自のヘッダーファイル(アプリ全体に広めたくない場合)に入れてみませんか。そうすれば、ヘッダーファイルをインクルードして、関数定義を好きな場所に配置できます。そうすることは標準のC機能です。

// Header file callback.h
void callback(
              ConstFSEventStreamRef streamRef,
              void *clientCallBackInfo,
              size_t numEvents,
              void *eventPaths,
              const FSEventStreamEventFlags eventFlags[],
              const FSEventStreamEventId eventIds[]);


// PNAppDelegate.m
#import "PNAppDelegate.h"
#import "callback.h"

@implementation PNAppDelegate

...

@end

void callback(
              ConstFSEventStreamRef streamRef,
              void *clientCallBackInfo,
              size_t numEvents,
              void *eventPaths,
              const FSEventStreamEventFlags eventFlags[],
              const FSEventStreamEventId eventIds[]) 
{
    [(__bridge PNAppDelegate *)clientCallBackInfo reloadStatus];

};
于 2012-07-18T20:48:37.290 に答える
1

あなたは正しいです、そのコードは醜いです。ただし、CとObj-Cのブリッジングは簡単な作業ではないため、実際にはいくつかのオプションしかありません。

  1. CベースのAPIの周りにObjective-Cラッパーを作成します。これは、特にAPIがそれほど複雑でない場合に、私の推奨するアプローチです。関数の代わりに、デリゲートまたはブロックのいずれかを使用できるという利点があります。

  2. 内部関数ポインタを取得して、コールバックにブロックを使用します。

    // internal structure of a block
    struct blockPtr {
        void *__isa;
        int __flags;
        int __reserved;
        void *__FuncPtr;
        void *__descriptor;
    };
    
    int main()
    {
        @autoreleasepool {
            __block int b = 0;        
    
            void (^blockReference)(void *) = ^(void *arg) {
                NSLog(@"<%s>: %i", arg, b++);
            };
    
    
            void *blockFunc = ((__bridge struct blockPtr *) blockReference)->__FuncPtr;
            void (*castedFunction)(void *, void *) = blockFunc;
    
            // the first argument to any block funciton is the block 
            // reference itself, similar to how the first argument to
            // any objc function is 'self', however, in most cases you
            // don't need the block reference (unless reading __block variables), it's just difficult to
            // get that first argument from inside the block
            castedFunction((__bridge void *) blockReference, "one");
            castedFunction((__bridge void *) blockReference, "two");
        }
    }
    

    これはほとんどの状況で実用的ではないと思いますが、それを機能させる方法を見つけることができれば、より多くの力を得ることができます。

  3. あなたが現在それをしている方法に固執してください。それはひどいです、しかしそれはCがどのように働くかです。

于 2012-07-18T21:01:03.180 に答える