Objective-C 对象转换为 C 回调函数

标签 objective-c c callback

目标:使用图案图像在 Quartz 2D 中进行绘制。目前:

const CGPatternCallbacks kPatternCallbacks = {0, routine, NULL};

void routine(void *info, CGContextRef contextRef) {

    UIImage *brushTexture = [UIImage imageNamed:@"PatternImage1"];

    CGContextDrawImage(contextRef, CGRectMake(0, 0, 50, 50), brushTexture.CGImage);
}

用于:

    CGPatternRef strokePattern = CGPatternCreate(NULL,
                                                 CGRectMake(0, 0, 50, 50),
                                                 CGAffineTransformIdentity,
                                                 50, // horizontal spacing
                                                 50, // vertical spacing
                                                 kCGPatternTilingNoDistortion,
                                                 true,
                                                 &kPatternCallbacks);

所有这些东西都在实现类(ViewController.m)中。非常完美,我可以绘制图案图像。

问题:动态更改 C 回调函数内的某些内容,例如:

在“ViewController.h”中

@interface ViewController : UIViewController {
    NSString *imageName;
}

@property (nonatomic, strong) NSString *imageName;

以及实现类(ViewController.m)

@synthesize imageName;

imageName = @"PatternImage1";

void routine(void *info, CGContextRef contextRef) {

    //UIImage *brushTexture = [UIImage imageNamed:@"PatternImage1"];

    //CGContextDrawImage(contextRef, CGRectMake(0, 0, 50, 50), brushTexture.CGImage);
    CGContextDrawImage(contextRef, CGRectMake(0, 0, 50, 50), imageName.CGImage);
}

错误!!! -> 使用未声明的标识符“imageName”

我已经尝试过了...

void routine(void *info, CGContextRef contextRef) {

    //NSString *imageName = CFBridgingRelease(info);     //<- not working

    //NSString *imageName = (__bridge NSString *)(info);  //<- not working

    NSString *imageName = (__bridge NSString *) info;     //<- not working


    //UIImage *brushTexture = [UIImage imageNamed:@"PatternImage1"];

    CGContextDrawImage(contextRef, CGRectMake(0, 0, 50, 50), imageName.CGImage);
}

例程结构不能更改,因为它是由 CGPatternCallbacks 定义的。

void routine(void *info, CGContextRef contextRef) { }

我搜索了很多,但没有找到解决方案。主题如下:

  • “将 Objective-C 对象传递给 C 函数”

  • “混合 Objective-C 和 C”

  • “回调函数”

  • “C 回调”

什么都没有,什么都没有,什么也没有。

不可能吗?我不这么认为!我将不得不放弃...F***!

最佳答案

传递给回调的 info 参数是您在调用 CGPatternCreate() 时作为 info 参数传递的任何值。在 Objective-C 代码中,您通常会传递 (__bridge void*)self。然后,在回调中,您将其转换回适当的类型并调用方法来完成实际工作:

void routine(void *info, CGContextRef contextRef) {
    ViewController* self = (__bridge ViewController*)info;
    [self drawPattern:contextRef];
}

- (void) drawPattern:(CGContextRef)contextRef {
    UIImage *brushTexture = [UIImage imageNamed:imageName]; // <- imageName can be an ivar
    CGContextDrawImage(contextRef, CGRectMake(0, 0, 50, 50), brushTexture.CGImage);
}

在非常简单的情况下,您只想传递图像名称字符串,您可以将该 NSString* 作为 info 指针传递。或者甚至是根据名称创建的 UIImage*,这样您就不必每次都创建它。这避免了在恢复的 self 上调用方法的需要。然而,即使您现在的需求很简单,也很容易有更复杂的需求,因此通常值得麻烦地传入 self

关于Objective-C 对象转换为 C 回调函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24290044/

相关文章:

iphone - UITextField 在 iOS 5 中导致崩溃,在 iOS 4 中工作正常

iphone - UIBarButtonItem外观iOS5字体

ios - Objective-C:在应用程序上播放 Youtube 视频

c++ - 非阻塞关闭 - 如何确保数据已发送?

c - 为什么整个结构在C中不能比较,却可以复制?

Objective-C:NULL、nil 和 @""之间有什么区别?

c - 将所有结构指针成员设置为 NULL

c - [GTK]将 g_signal_connect 中的循环计数器传递给 g_callback

javascript - 如何在打开事件时获取放大弹出 API 的 url?

swift - "return function"和 "callback function"之间的主要区别是什么?