2009-06-12 37 views
8

它在錫上說什麼:我想使用@property/@synthesize語法來定義我的Objective-C 2.0類的一個屬性,但是我想限制屬性中允許的值的範圍。例如:我可以使用@synthesized方法在Objective-C中驗證@property值嗎?

@interface MyClass : NSObject { 
    int myValue; 
} 

@property (nonatomic) int myValue; 

實現:

@implementation MyClass 

@synthesize myValue(test='value >= 0'); 

請注意,這裏的語法僅僅是一個例子。這是,還是很可能的事情?或者,合成的setter的字面值相當於什麼,以便我可以確保在手動設置器中使用與合成器中使用的相同的對象保留規則。

+0

這可能值得用'cocoa'和'macosx'來標記。我沒有足夠的聲譽。 – toholio 2009-06-12 04:52:25

回答

7

假設你的屬性是鍵 - 值兼容,你也應該實現鍵值兼容驗證程序(因爲如果你使用@synthesize他們會)。看看蘋果關於此事的文檔: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實例中的整數來做到這一點。

+4

根據文檔,您不應該在setter中調用驗證方法:http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/KeyValueCoding/Articles/Validation.html#//apple_ref/doc/UID/20002173-166962 – 2012-01-22 18:06:10

2

當您使用@synthesize時,會生成訪問器方法。你可以實現你自己的,它會覆蓋生成的。

您可以將自己的實現放在訪問器方法中,例如您可以在分配之前添加值檢查等等。

您可以省略其中一個或另一個或兩者,因爲@synthesize會生成您未實現的那些,如果您使用@dynamic,則指定您將在編譯或運行時提供訪問器。

訪問者將具有從屬性名稱mypropertysetMyproperty派生的名稱。方法簽名是標準的,所以很容易實現你自己的。實際的實現取決於屬性定義(複製,保留,分配),如果它是隻讀的(只讀沒有獲取set訪問器)。有關更多詳細信息,請參閱objective-c參考。

Apple reference:

@synthesize你使用@synthesize 關鍵字告訴它應該 合成setter和/或財產 getter方法編譯器,如果你 的 內不提供他們@implementation塊。

@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 
相關問題