2

这就是我要在这个程序中实现的内容

@interface settings : CBLModel

@property (copy) NSString* foo;

- (instancetype) initInDatabase: (CBLDatabase*)database withAllValues:(NSDictionary*)gameDic ChannelId:(NSString*)chann_id;

在 .m 文件中,我正在使用这个...

@implementation settings
@dynamic foo;

- (instancetype) initInDatabase: (CBLDatabase*)database
                  withAllValues: (NSDictionary*)gameDic ChannelId:(NSString*)chann_id
{
    NSParameterAssert(gameDic);
    self = [super initWithNewDocumentInDatabase: database];
    if (self) {
        self.foo=@"value";//this is where it crashes
    }
    return self;
}

-(void)setfoo:(NSString *)foo{
  foo=[foo copy];//tried doin this but the value is not assigned

}

我正在尝试设置导致崩溃的动态属性的值。我需要使用动态,因为我想将其反映在服务器上,而使用合成不会这样做。

4

3 回答 3

2

首先,你的属性是小写foo的,动态声明是大写的Foo。这可能是导致问题的原因。但假设这只是一个错字,

@dynamic foo;

告诉编译器它不应该属性合成 getter 和 setter 方法。这是一个“承诺”,所需的访问器方法将在运行时以某种方式提供。由于您不提供 setter 方法,

self.foo = @"abc";

必须在运行时崩溃。

因此,除非您有明确的原因,否则您只需删除@dynamic声明,编译器将在必要时合成 getter、setter 和实例变量。

如果您解释您要达到的目标,可能会有更好的答案。

备注:如果您的自定义setFoo:进入无限循环,那么您可能会在 setter 方法中使用属性 setter,而不是直接访问实例变量。一个简单的例子:

-(void)setFoo:(NSString *)foo
{
    // wrong: self.foo = [foo copy];
    _foo = [foo copy];
}

更新:上面的答案是在我知道“设置”是“Couchbase Lite”的“CBLModel”的子类之前写的。我没有使用该框架的经验,但是从阅读文档看来,@dynamic foo;在这种情况下确实是正确的,并且setFoo:应该在子类中实现,因为 Couchbase 框架在运行时创建了必要的访问器方法。

能看到的唯一可能的错误是自定义初始化程序应该调用

self = [self initWithNewDocumentInDatabase: database];

代替

self = [super initWithNewDocumentInDatabase: database];
于 2013-10-20T08:41:37.890 回答
0

尝试@property(copy) NSString* foo;改变@property (nonatomic, strong) NSString *foo;

于 2013-10-20T08:28:04.560 回答
0

@dynamicproperty 表示 setter 和 getter 的实现将由运行时的一些底层代码提供。它通常NSManagedObject用于Core Data. @dynamic如果您的对象是 的子类,则没有基础代码来管理您的属性NSObject,因此您负责实现 setter 和 getter。更改@dynamic@synthesize让编译器为您创建适当的 setter 和 getter。

UPD:从最新的编译器开始,您可以忽略Martin R@synthesize所说的。

于 2013-10-20T08:42:04.297 回答