它上面说的内容:我想使用@property
/ @synthesize
语法在Objective-C 2.0类上定义属性,但我想对范围进行限制属性中允许的值。例如:
@interface MyClass : NSObject {
int myValue;
}
@property (nonatomic) int myValue;
实现:
@implementation MyClass
@synthesize myValue(test='value >= 0');
请注意,此处的语法只是一个示例。是这样,还是可能的东西?或者,什么是合成setter的文字等价物,这样我就可以确保在手动setter中使用与合成setter中相同的对象保留规则。
答案 0 :(得分:8)
假设您的属性符合键值(如果您使用@synthesize那样),您还应该实现符合键值的验证器。请查看Apple关于此事的文档:http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/Validation.html
需要注意的重要一点是,除非使用某些类型的绑定,否则验证不会自动发生。您可以直接调用验证器,也可以调用validateValue:forKey:error:
。
您可以覆盖生成的setter以在保存之前调用验证器但是如果您正在使用绑定,这可能不是您想要执行的操作,因为对于单个修改,验证器可能会被多次调用。
另请注意,验证程序可能会更改要验证的值。
让我们看看你的例子(未经测试,顺便说一下。我不在Mac附近):
@implementation MyClass
@synthesize myValue;
-(BOOL)validateMyValue:(id *)ioValue error:(NSError **)outError
{
if (*ioValue == nil) {
// trap this in setNilValueForKey
// alternative might be to create new NSNumber with value 0 here
return YES;
}
if ( [*ioValue intValue] < 0 ) {
NSString *errorString = @"myValue must be greater than zero";
NSDictionary *userInfoDict = [NSDictionary dictionaryWithObject:errorString
forKey:NSLocalizedDescriptionKey];
NSError *error = [[[NSError alloc] initWithDomain:@"MyValueError"
code:0
userInfo:userInfoDict] autorelease];
*outError = error;
return NO;
} else {
return YES;
}
}
如果你想覆盖合成的setter并让它进行验证(仍未经测试):
- (void)setMyValue:(int)value {
id newValue = [NSNumber numberWithInt:value];
NSError *errorInfo = nil;
if ( [self validateMyValue:&newValue error:&errorInfo] ) {
myValue = [newValue intValue];
}
}
你可以看到我们必须在NSNumber实例中包装整数来执行此操作。
答案 1 :(得分:3)
使用@synthesize时,会生成访问器方法。您可以实现自己的覆盖生成的。
您可以将自己的实现放在访问器方法中,例如您可以在分配前添加值检查等。
您可以省略其中一个或两个,由于@synthesize将生成未实现的那些,如果您使用@dynamic,则指定您将在编译或运行时提供访问器。 / p>
访问者将使用从属性名称myproperty
和setMyproperty
派生的名称。方法签名是标准的,因此很容易实现自己的签名。实际的实现取决于属性定义(复制,保留,赋值)以及它是否为只读(只读不设置访问器)。有关更多详细信息,请参阅objective-c reference。
@synthesize你使用@synthesize 关键字告诉编译器它 应该合成二传手和/或 如果您属性的getter方法 不要在里面供应它们 @implementation block。
@interface MyClass : NSObject
{
NSString *value;
}
@property(copy, readwrite) NSString *value;
@end
@implementation MyClass
@synthesize value;
- (NSString *)value {
return value;
}
- (void)setValue:(NSString *)newValue {
if (newValue != value) {
value = [newValue copy];
}
}
@end