2

Objective-C プログラミングと Xcode は初めてです。プロジェクトの古いバージョン (3.2.5) を継承し、最近それを最新バージョン (4.5.2) に変換しました。このプロジェクトを ARC に変換しましたが、typedef 構造体内にある object-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 でも機能するコードに変換するにはどうすればよいですか?

編集:さて、私は CFTypeRef を使用して Jano の提案を使用しました。同じコード行で同じクラッシュ (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;
    }
}

ご提案いただきありがとうございます。

4

3 に答える 3

1

を使用__unsafe_unretainedし、その特定の構造体フィールドの明示的な保持/解放を再導入します。おそらくこれは以前は機能していたので、今日機能しない理由はありません。

もちろん、ARC では-retainandを呼び出すことはできません-release。ただし、obj-c オブジェクトで呼び出された場合と同じことを行うCFRetain()andを呼び出すことができます。CFRelease()

または、コードを Obj-C++ に変換する場合は__strong、C++ 構造体にオブジェクトを埋め込むことができ、コンパイラは正しいデストラクタを生成します。

于 2012-12-03T22:51:59.533 に答える
0

このコードを *image オブジェクトを保持しながら ARC でも機能するコードに変換するにはどうすればよいですか?

struct _BitmapFontChar1 つの方法は、適切な Objective-C クラスに変換することです。その後、他の Obj-C オブジェクトを参照しても問題ありません。

于 2012-12-03T22:45:05.963 に答える
-1

ケビンとカレブが言ったこと。

これを自分で試してみたかったので、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 は __unsafe_unretained の代替である単なる void* であり、CFBridging 関数は、Objc ポインターを Core Foundation にキャストし (CFBridgingRetain)、戻す (CFBridgingRelease)。

最も簡単な方法は、軽量オブジェクトを作成して ARC に処理させることです。

于 2012-12-03T23:38:54.030 に答える