3

我想传递 2 个变量:

UIImage * img
int i

进入另一种只需要 (void *) 的方法

我尝试制作一个包含 img 和 i 的 C 结构

struct MyStruct {
    UIImage *img;
    int i;
}

但是 xcode 给了我一个错误,说“ARC 禁止在结构或联合中使用 Objective-C 对象”

接下来我尝试编写一个包含 img 和 i 的 Objective-c 类 MyStruct2,分配初始化它的一个实例并将其类型转换为 (__bridge void*),然后将其传递给方法。我的用例似乎很少涉及。似乎应该有更好的方法。

实现这一目标的最简单方法是什么?

谢谢你。

根据评论进行编辑:我必须使用 void *,因为它是 UIView API 的要求。我创建了 UIVIew API 提到的选择器

+ (void)setAnimationDidStopSelector:(SEL)selector

请参阅http://developer.apple.com/library/ios/#documentation/uikit/reference/UIView_Class/UIView/UIView.html上的 setAnimationDidStopSelector 文档。它说...选择器应采用以下形式:

    - (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context 

我想将 img 和 i 都传递给 (void *)context 参数。

4

2 回答 2

4

你可以这样做:

struct MyStruct {
    __unsafe_unretained UIImage *img;
    int i;
}

但是,如果您这样做,您必须记住该img字段不会自动保留和释放其UIImage.

如果您发布有关“仅需要 (void *) 的方法”的更多详细信息,我们也许可以为您提供更好的建议。

编辑

您已经更新了您的问题,说您需要将 a 传递void *animationDidStop:finished:context:选择器。由于您使用的是 ARC,我知道您的目标是 iOS 4.0 或更高版本,因此您应该 animateWithDuration:animations:completion:改用。然后你不需要传递一个void *.

UIImage *img = someImage();
int i = someInt();

[UIView animateWithDuration:2.0 animations:^{
    // set the animatable properties here
} completion:^(BOOL finished) {
    doSomethingWithImageAndInteger(img, i);
}];
于 2012-06-23T20:35:43.883 回答
3

ARC 不能在普通的旧 C 结构中跟随 ObjC 对象。它跟踪堆栈上的指针,或者 ObjC 和 C++ 对象中的指针,这些指针是使用显式或隐式方法复制的,但无论如何都在编译器控制之下。

所以......使用一个类。如果你喜欢 C++,或者:

@interface MyNotSoPlainStruct

@property ( nonatomic, strong ) UImage* image;
@property ( nonatomic ) int i;

@end

@implementation MyNotSoPlainStruct
@end

MyNotSoPlainStruct* foo = [MyNotSoPlainStruct new];
foo.image = …
foo.i = …

你去吧。

解决方案需要更多行,这是真的,但您可以更好地控制事情的完成方式,包括图像生命周期。如果它更适合您的需要,您可以使用强指针或弱指针。

当然,您也可以使用字典或数组。文字使这变得特别容易:

NSDictionary* arguments = @{ @"image" : <image>, @"i" : @( <int> ) };
arguments[@"i"].intValue returns the int you need.

相当容易。

编辑

忘了转移部分,哎呀:)。那么:

您必须使用以下注释:

void* argumentsPointer = (__bridge_retained void*) arguments;

参数被保留,并且该引用不再由 ARC 管理。

当您收到指针返回时,您必须将其转换:

NSDictionary* arguments = (__bridge_transfer NSDictionary*) argumentsPointer;

如果最后一个已知引用消失,仅使用 __bridge 可能会导致指针悬空。如果您希望 void* 保留字典,则必须先使用 __bridge_retained,然后再使用 __bridge_transfer。

于 2012-06-23T20:45:49.180 回答