首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将目标C与C和代码组织混合

将目标C与C和代码组织混合
EN

Stack Overflow用户
提问于 2012-07-18 20:40:15
回答 2查看 414关注 0票数 1

我正在开发一个使用fileevent监视文件夹的桌面应用程序,基本上这是我的代码:

代码语言:javascript
运行
复制
#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混合在一起)。以下是我的问题:

  • 我应该在哪里申报我的回拨?把它放在我文件的顶端感觉很奇怪,就因为它在那里起作用了。
  • 有可能有某种基于@selector的方法而不是回调吗?(我觉得他们令人放心:D)

谢谢你抽出时间!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-18 21:01:03

你是对的,那个代码很难看。但是,桥接C和Obj-C是no small task,所以您实际上只有几个选项:

  1. 围绕基于C的API创建一个Objective包装器.这将是我推荐的方法,特别是如果API不是太复杂的话。它提供了使用委托或块而不是函数的优势。
  2. 使用块进行回调,方法是获取其内部函数指针: //块结构blockPtr { void *__isa;int __flags;int __reserved;void *__FuncPtr;void *__descriptor;};int main() { __block int b= 0;void (^ block __reserved)(void *) = ^(void *arg) {NSLog(@<%s>:%i,arg,b++);};void *blockFunc = ((__bridge struct blockPtr *) blockReference)->__FuncPtr;->__FuncPtr (*castedFunction)(void *,void *) = blockFunc;//任何块函数的第一个参数是块//引用本身,类似于//任何objc函数的第一个参数是'self',但是,在大多数情况下,您//不需要块引用(除非读取__block变量),就很难从块castedFunction(__bridge void *) blockReference中获取第一个参数( "one");castedFunction((__bridge void *) blockReference,“2”);} 我真的不认为这在大多数情况下是可行的,但是如果你能找到一种方法让它发挥作用,那就给你更多的动力。
  3. 坚持你目前的做法。这很糟糕,但这就是C的工作方式。
票数 1
EN

Stack Overflow用户

发布于 2012-07-18 20:48:37

为什么不将回调声明放在PNAppDelegate.h或它自己的头文件中(如果您不想在应用程序中传播它)。这样,您就可以只包含头文件,并将函数定义放在任何您想要的位置。这样做是标准C功能。

代码语言:javascript
运行
复制
// 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];

};
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11549955

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档