它在锡上说的内容:我想使用@property
/ @synthesize
语法在Objective-C 2.0类上定义属性,但我想对属性中允许的值范围进行限制.例如:
@interface MyClass : NSObject { int myValue; } @property (nonatomic) int myValue;
执行:
@implementation MyClass @synthesize myValue(test='value >= 0');
请注意,此处的语法只是一个示例.是这样,还是可能的东西?或者,什么是合成setter的文字等价物,以便我可以确保在我的手动设置器中使用与合成设置器中使用的相同的对象保留规则.
假设您的属性符合键值(如果使用@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实例中包装整数来执行此操作.