我是Objective-C编程和Xcode的新手。我继承了一个项目的旧版本(3.2.5),最近我把它转换为最新版本(4.5.2)。我将这个项目转换为ARC,我遇到了在typedef结构中找到的objective-c对象的问题:
typedef struct _BitmapFontChar {
int charID;
int x;
int y;
int width;
int height;
int xOffset;
int yOffset;
int xAdvance;
Image * image; // Objective-C object in struct forbidden in ARC
float scale;
} BitmapFontChar;
当我尝试使用__unsafe __unretained_
时,它在ARC中编译得很好,但该项目不再起作用。当然,* image对象不会被保留,我的项目也会崩溃。
结构使用如下:
@interface BitmapFont : NSObject {
GameController * sharedGameController;
Image * image;
BitmapFontChar * charsArray; // typedef struct
int commonHeight;
Color4f fontColor;
}
...
charsArray = calloc(kMaxCharsInFont, sizeof(BitmapFontChar));
如何将此代码转换为保留*image
对象的内容,但也可以在ARC中使用?
编辑: 好的,我使用了Jano建议使用CFTypeRef。我仍然在同一行代码中遇到相同的崩溃(EXC_BAD_ACCESS)。我想我没有正确使用CFBridgingRetain。下面是我的.h文件:
#import "Global.h"
@class Image;
@class GameController;
#define kMaxCharsInFont 223
typedef struct _BitmapFontChar {
int charID;
int x;
int y;
int width;
int height;
int xOffset;
int yOffset;
int xAdvance;
CFTypeRef image;
float scale;
} BitmapFontChar;
enum {
BitmapFontJustification_TopCentered,
BitmapFontJustification_MiddleCentered,
BitmapFontJustification_BottomCentered,
BitmapFontJustification_TopRight,
BitmapFontJustification_MiddleRight,
BitmapFontJustification_BottomRight,
BitmapFontJustification_TopLeft,
BitmapFontJustification_MiddleLeft,
BitmapFontJustification_BottomLeft
};
@interface BitmapFont : NSObject {
GameController *sharedGameController;
Image *image;
BitmapFontChar *charsArray;
int commonHeight;
Color4f fontColor;
}
@property(nonatomic, strong) Image *image;
@property(nonatomic, assign) Color4f fontColor;
- (id)initWithFontImageNamed:(NSString*)aFileName ofType:(NSString*)aFileType
controlFile:(NSString*)aControlFile scale:(Scale2f)aScale filter:(GLenum)aFilter;
- (id)initWithImage:(Image *)aImage controlFile:(NSString *)aControlFile
scale:(Scale2f)aScale filter:(GLenum)aFilter;
-(void)renderStringAt:(CGPoint)aPoint text:(NSString*)aText;
-(void)renderStringJustifiedInFrame:(CGRect)aRect justification:(int)aJustification
text:(NSString*)aText;
-(int)getWidthForString:(NSString*)string;
-(int)getHeightForString:(NSString*)string;
@end
以下是我的.m文件的一部分,其中包含发生崩溃的方法和代码行:
-(void)renderStringAt:(CGPoint)aPoint text:(NSString*)aText {
float xScale = image.scale.x;
float yScale = image.scale.y;
for(int i=0; i<[aText length]; i++) {
unichar charID = [aText characterAtIndex:i] - 32;
int y = aPoint.y + (commonHeight * yScale) - (charsArray[charID].height
+ charsArray[charID].yOffset) * yScale;
int x = aPoint.x + charsArray[charID].xOffset;
CGPoint renderPoint = CGPointMake(x, y);
CFTypeRef vpImage = CFBridgingRetain(image); //???
((__bridge Image *)(charsArray[charID].image)).color = fontColor;//CRASH EXC_BAD_ACCESS
[((__bridge Image *)(charsArray[charID].image)) renderAtPoint:renderPoint];
aPoint.x += charsArray[charID].xAdvance * xScale;
}
}
再次感谢您的建议!
答案 0 :(得分:1)
使用__unsafe_unretained
,并重新引入该特定结构域的显式保留/释放。据推测,这之前有用,所以没有理由今天无法工作。
当然,ARC不允许您致电-retain
和-release
。但它确实允许你调用CFRetain()
和CFRelease()
,它们在obj-c对象上调用时会做同样的事情。
或者,如果要将代码转换为Obj-C ++,可以在C ++结构中嵌入__strong
对象,编译器将为您生成正确的析构函数。
答案 1 :(得分:0)
如何将此代码转换为保留*图像的代码 对象,但也可以在ARC中工作吗?
一种方法是将struct _BitmapFontChar
转换为适当的Objective-C类。然后可以引用其他Obj-C对象。
答案 2 :(得分:-1)
Kevin和Caleb说的话。
因为我想自己尝试这个,这是CodeRunner的一个小例子:
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
@autoreleasepool {
typedef struct _person {
char name[25];
CFTypeRef avatar;
} person;
NSObject *avatar = [NSObject new];
CFTypeRef vpAvatar = CFBridgingRetain(avatar);
person carol = { "Carol", vpAvatar };
CFBridgingRelease(carol.avatar);
}
}
CFRefType只是一个void *,它是__unsafe_unretained的替代品,CFBridging函数将一个Objc指针强制转换为Core Foundation(CFBridgingRetain)并返回(CFBridgingRelease)。
最简单的事情似乎是创建一个轻量级对象,让ARC处理它。