سؤال

I'm beginning to learn how use Core Data for my app, and I have a question about setter and getter with NSManagedObject.

In my old models I was using this syntax to declare attributes :

@interface MyModel : NSObject 
{
    MyAttributeOfClass *_myAttributeOfClass
}

- (void)setMyAttributeOfClass:(MyAttributeOfClass *)anAttributeOfClass;
- (MyAttributeOfClass *)myAttributeOfClass;

I know, I could use @synthesize for doing this stuff. But if I use @synthesize with a public attribute like :

@property (nonatomic, strong) MyAttributeOfClass *myAttributeOfClass;

A developer could bypass my setter and directly set a value for myAttributeOfClass by doing this: myAttributeOfClass = bar;. I don't want to allow this behaviour because I use a setter to perform an action. If this action is not done, my class will no longer work correctly.

So, now I am migrating my old model to Core Data model subclassed from NSManagedObject.

But when I generate classes from my data model, the attributes are declared this way:

@property (nonatomic, retain) MyAttribute *myAttribute;

So, a developer can set a value for this attribute without calling a setter: myAttribute = bar; and I would like forbid it.

Any suggestions ?

Thanks !

هل كانت مفيدة؟

المحلول

The attributes of Core Data managed objects are not backed-up by instance variables. An attribute can be set using the property syntax:

object.myAttribute = bar;

or with Key-Value Coding:

[object setValue:bar forKey:@"myAttribute"];

and in both cases the setter method

-(void)setMyAttribute:(MyAttribute *)value;

is called. Setter and getter method are usually created dynamically at runtime, but you can provide your own explicit setter and/or getter method.

However, it is possible to bypass the setter by calling the "primitive" accessor methods:

[object setPrimitiveValue:bar forKey:@"myAttribute"];

This is what a custom setter method would use, but anybody can call the primitive accessor, there is no way to inhibit that.

نصائح أخرى

My approach when I want to have a private setter is to have this in the header:

@property (nonatomic, strong, readonly) NSString*  myProperty;

And then in the .m file add:

@interface MyClass ()
@property (nonatomic, strong) NSString* myProperty;
@end

Externally the property is read-only, but by defining a private category in the implementation file, the property is readwrite within the implementation.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top