我想传递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参数。
答案 0 :(得分:4)
你可以这样做:
struct MyStruct {
__unsafe_unretained UIImage *img;
int i;
}
但是,如果您这样做,则必须牢记img
字段不会自动保留并释放其UIImage
。
如果您发布有关“仅采用a(void *)”的方法的更多详细信息,我们可能会为您提供更好的建议。
您已更新问题,说明您需要将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);
}];
答案 1 :(得分: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.
非常简单。
修改强>
忘记转移部分,oops :)。那么:
您必须使用以下注释:
void* argumentsPointer = (__bridge_retained void*) arguments;
保留参数,并且该引用不再由ARC管理。
当您接收指针时,必须转换它:
NSDictionary* arguments = (__bridge_transfer NSDictionary*) argumentsPointer;
如果最后一个已知引用消失,则仅使用__bridge可能会导致悬空指针。如果您希望void *保留字典,则必须先使用__bridge_retained,然后使用__bridge_transfer。