我在Objective-C代码中写了这篇文章,作为斯坦福大学关于iOS编程的iTunes U课程的一部分。有没有办法简化这段代码?要求是如果set为空,则此方法返回nil,而不是空NSSet。它还需要一个(id),而不是NSArray,并且无论传递给它的是什么值,该方法都不会崩溃。
+ (NSSet *)variablesUsedInProgram:(id)program {
NSMutableArray *stack;
id variables;
NSMutableSet *setOfVariables;
if ([program isKindOfClass:[NSArray class]]) {
stack = [program mutableCopy];
int i = stack.count;
while (i--) {
if ([[stack objectAtIndex:i] isKindOfClass:[NSString class]]) {
if ([self isOperation:[stack objectAtIndex:i]]) {
[setOfVariables addObject:[stack objectAtIndex:i]];
}
}
}
}
if (setOfVariables.count > 0) {
variables = setOfVariables;
}
return variables;
}
答案 0 :(得分:1)
variables
和setOfVariables
永远不会被初始化。在setOfVariables
(假设它已初始化)的计数为0的情况下,该方法将返回未初始化的值。我不确定为什么你需要program
的可变副本,因为你永远不会修改数组。我不确定为什么你实际上需要它的副本,而你实际上也没有释放它(如果你使用ARC或GC,那就没关系,但如果你使用的是MRC则没有)。这就是我重构它的方式,可观察的行为不应该与你的方法不同。
+ (NSSet *)variablesUsedInProgram:(id)program
{
if (![program isKindOfClass:[NSArray class]])
return nil;
NSMutableSet *setOfVariables = [NSMutableSet set];
foreach (id object in program)
if ([self isOperation:object])
[setOfVariables addObject:object];
if (setOfVariables.count > 0)
return setOfVariables;
else
return nil;
}
答案 1 :(得分:1)
在我的头脑中,这是一个相当简短的方法:
+ (NSSet *)variablesUsedInProgram:(id)program {
if (![program isKindOfClass:[NSArray class]])
return nil;
Class stringClass = [NSString class];
NSSet *setOfVariables =
[program objectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop){
return ([obj isKindOfClass:stringClass] && [self isOperation:obj]);
}];
return setOfVariables.count ? setOfVariables : nil;
}
答案 2 :(得分:0)
快速枚举应该适用于这种情况。
+ (NSSet *)variablesUsedInProgram:(id)program {
NSMutableArray *stack;
id variables;
NSMutableSet *setOfVariables;
if ([program isKindOfClass:[NSArray class]]) {
stack = [program mutableCopy];
for (NSString *string in stack)//Fast enumerate through the array for NSString's
{
if ([self isOperation:string]) {
[setOfVariables addObject:string];
}
}
}
if (setOfVariables.count > 0) {
variables = setOfVariables;
}
return variables;
}