Objective-C中检查isKindOfClass是否冗余?含Swift代码审核场景
isKindOfClass: Redundant for Non-id Variables in Objective-C? Great question—this is a common point of confusion with Objective-C's dynamic typing system, so let's unpack it step by step.
First, let's look at your code snippet:
-(void) checkCalorie:(NSMutableDictionary *) update { NSString *foodInfoId = [update objectForKey:FOOD_INFO_ID]; double calorie = [[update objectForKey:CALORIE] doubleValue]; if ([foodInfoId isKindOfClass:[NSString class]] && calorie < 0) { calorie = 0.0; // some logic } }
Why the isKindOfClass: Check Isn't Redundant
At first glance, since foodInfoId is declared as an NSString*, it might seem like the type check is unnecessary. But here's the key detail:
[update objectForKey:]returns anidtype—Objective-C's generic object pointer. The static declarationNSString *foodInfoIdis just a hint to the compiler; it doesn't guarantee that the object returned from the dictionary is actually anNSString(or its subclass) at runtime.- If someone accidentally stores a non-string value (like an
NSNumberorNSNull) under theFOOD_INFO_IDkey in the dictionary,foodInfoIdwill still compile, but calling NSString-specific methods on it later would lead to runtime crashes. TheisKindOfClass:check acts as a safety guard against this scenario.
A Small Optimization for Clarity
While the check is valid, you can restructure the code to make the type safety more explicit:
-(void) checkCalorie:(NSMutableDictionary *) update { id rawFoodInfoId = [update objectForKey:FOOD_INFO_ID]; NSString *foodInfoId = nil; if ([rawFoodInfoId isKindOfClass:[NSString class]]) { foodInfoId = rawFoodInfoId; } double calorie = [[update objectForKey:CALORIE] doubleValue]; if (foodInfoId && calorie < 0) { calorie = 0.0; // some logic } }
This way, you separate the raw value retrieval from the type check, making it clearer that foodInfoId is only non-nil if it's a valid string.
One Quick Note on isKindOfClass: vs isMemberOfClass:
Just to clarify: isKindOfClass: checks if the object is an instance of the specified class or any of its subclasses (which is usually what you want, since NSMutableString should be treated like an NSString). If you strictly wanted only instances of NSString (not subclasses), you'd use isMemberOfClass:, but that's rare in most practical cases.
内容的提问来源于stack exchange,提问作者Sazzad Hissain Khan

