我试图在 Objective-C 中包装一个 C API,但在 objc_release 中得到 EXC_BAD_ACCESS。
字段.h:
#ifdef __cplusplus
extern "C" {
#endif
struct sc_field
{
char *title;
};
typedef struct sc_field sc_field_t;
sc_field_t* sc_create_field();
void sc_destroy_field(sc_field_t *field);
const char* sc_get_title(const sc_field_t *field);
void sc_set_title(sc_field_t *field, const char *title);
#ifdef __cplusplus
}
#include <string>
class Field
{
public:
explicit Field();
virtual ~Field();
std::string title() const;
void setTitle(const std::string &title);
private:
class Private;
Private *d;
};
字段.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Field.h"
sc_field_t* sc_create_field()
{
sc_field_t *field = (sc_field_t*)malloc(sizeof(sc_field_t));
field->title = (char*)calloc(1, sizeof(char));
return field;
}
void sc_destroy_field(sc_field_t *field)
{
if (field)
{
free(field->title);
free(field);
}
}
const char* sc_get_title(const sc_field_t *field)
{
if (!field)
{
fprintf(stderr, "%s: fatal error, field is NULL\n", __FUNCTION__);
return NULL;
}
return field->title;
}
void sc_set_title(sc_field_t *field, const char *title)
{
if (!field)
{
fprintf(stderr, "%s: fatal error, field is NULL\n", __FUNCTION__);
return;
}
field->title = (char*)realloc(field->title, sizeof(char) * sizeof(title));
strcpy(field->title, title);
}
SCField.h:
#import "Field.h"
#import <Foundation/Foundation.h>
@interface SCField : NSObject
{
@private
sc_field_t *field;
}
@property (nonatomic, copy) NSString *title;
- (id)init;
- (id)initWithTitle:(NSString *)title;
- (void)dealloc;
@end
SCField.m:
#import "SCField.h"
@implementation SCField
@synthesize title;
- (id)init
{
self = [super init];
if (self)
{
field = sc_create_field();
}
return self;
}
- (id)initWithTitle:(NSString *)aTitle
{
self = [self init];
if (self)
{
[self setTitle:aTitle];
}
return self;
}
- (void)dealloc
{
sc_destroy_field(field);
[super dealloc];
}
- (NSString *)title
{
return [NSString stringWithUTF8String:sc_get_title(field)];
}
- (void)setTitle:(NSString *)aTitle
{
sc_set_title(field, [aTitle UTF8String]);
}
@end
测试:
SCField *field = [[SCField alloc] initWithTitle:@"Hello world!"];
NSLog(@"%@\n", [field title]);
[field release];
在我发布我的 SCField 实例之前,代码似乎工作正常。如果我删除标题和 setTitle: 实现,就好像我直接在 SCField 中存储一个 NSString* 代码工作正常(我也尝试在 @property 中分配而不是复制 - 不走运)。我究竟做错了什么?