是否有可能创建自定义注解来检查方法的参数是空数组还是空字符串?类似Java中的@NotEmpty。我已经使用_Nonnull和NSParameterAssert检查参数,但我很好奇我们是否可以写自定义注解?谢谢。
你可以使用宏来定义一个内联函数。
#define isNil(x) nil ==x
Objective-C没有这种可定制的注解,但它的主要优势之一是它运行时的通用性。
因此,如果我们真的想这样做,我们可以用一个包装类类型来实现。
@interface NotEmpty<Object> : NSProxy
@property(readonly,copy) Object object;
+ (instancetype)notEmpty:(Object)object;
- (instancetype)initWithObject:(Object)object;
@end
@implementation NotEmpty {
id _object;
}
- (id)object {
return _object;
}
+ (instancetype)notEmpty:(id)object {
return [[self alloc] initWithObject:object];
}
- (instancetype)initWithObject:(id)object {
if ([object respondsToSelector:@selector(length)]) {
NSParameterAssert([object length] != 0);
} else {
NSParameterAssert([object count] != 0);
}
_object = [object copy];
return self;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
if (selector == @selector(object)) {
return [NSMethodSignature signatureWithObjCTypes:"@:"];
} else {
return [_object methodSignatureForSelector:selector];
}
}
- (void)forwardInvocation:(NSInvocation *)invocation {
invocation.target = _object;
[invocation invoke];
}
@end
@interface SomeClass : NSObject
@end
@implementation SomeClass
- (void)method:(NotEmpty<NSString*> *)nonEmptyString {
// Call NSString methods, option 1
unsigned long length1 = [(id)nonEmptyString length];
// Call NSString methods, option 2
unsigned long length2 = nonEmptyString.object.length;
// Note that just printing `nonEmptyString` (not nonEmptyString.object)
// will print an opaque value. If this is a concern, then also forward
// @selector(description) from -methodSignatureForSelector:.
NSLog(@"Received: %@ (length1: %lu length2: %lu)", nonEmptyString.object, length1, length2);
}
@end
int main() {
SomeClass *sc = [SomeClass new];
[sc method:[NotEmpty notEmpty:@"Not an empty string"]];
// [sc method:[NotEmpty notEmpty:@""]]; // Raises error
}
请注意,这样做会造成一些小的性能损失。