在iPhone应用程序的发布配置中无休止的“for”循环

时间:2011-07-21 21:16:46

标签: iphone objective-c

我的申请中有以下代码:

NSArray *lstAttributes = [conditionAttribute componentsSeparatedByString:cstrSystemUIConfigurationAttributeConditionSeparator],
    *lstValues = [conditionValue componentsSeparatedByString:cstrSystemUIConfigurationAttributeConditionSeparator],
    *lstValueTypes = [conditionValueType componentsSeparatedByString:cstrSystemUIConfigurationAttributeConditionSeparator];

if([lstAttributes count] != [lstValues count] ||
   [lstAttributes count] != [lstValueTypes count]) return NO;

BOOL bResult = YES;
NSLog(@"attributes amount - %u", [lstAttributes count]);
for(uint i = 0; i < [lstAttributes count]; i ++)
{
    NSLog(@"counter: %u", i);
    SystemUIConfigurationAttributeCondition *condition = [SystemUIConfigurationAttributeCondition new];

    condition.conditionAttribute = [lstAttributes objectAtIndex:i];
    condition.conditionValue = [lstValues objectAtIndex:i];
    condition.conditionValueType = [lstValueTypes objectAtIndex:i];

    bResult &= [self checkCondition:condition forOwner:owner];

    FreeObject(&condition);

    if(!bResult) break;
}

return bResult;

“debug”配置中的一切都很好。但是一旦我把它切换到“释放”,我面对无限循环。控制台向我显示以下内容:属性数量 - 2,计数器:0,计数器:1,计数器:1,计数器:1,计数器:1,计数器:1,计数器:1,......等。

我试图使用不同的“for”和“while”运算符,但没有任何正常工作。循环仍然无法停止。

以前有人遇到过同样的问题吗?

2 个答案:

答案 0 :(得分:1)

承诺提供此错误的解决方法:

起初我尝试使用代码块来枚举列表中的所有对象而不是“for”循环。

__block BOOL bResult = YES;
[lstAttributes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
{
    SystemUIConfigurationAttributeCondition *condition = [SystemUIConfigurationAttributeCondition new];

    condition.conditionAttribute = [lstAttributes objectAtIndex:idx];
    condition.conditionValue = [lstValues objectAtIndex:idx];
    condition.conditionValueType = [lstValueTypes objectAtIndex:idx];

    bResult &= [self checkCondition:condition forOwner:owner];

    FreeObject(&condition);

    if(!bResult) *stop = YES;
}];

但我在第二次迭代时遇到了崩溃。 “lstValues”和“lstValueTypes”指针突然改变了它们的值,应用程序收到了EXC_BAD_ACCESS。可能使用3个数组,而枚举其中只有1个不是一个好主意。调试器显示枚举是在同一个线程上执行的,但是在第二次迭代时,3个阵列中有2个被破坏。

所以我决定将我的初始循环分成两部分:

  1. 准备条件清单
  2. 检查每个条件。
  3. 首先是通常的“for”循环,第二个是'NSArray类的'enumerateObjectsUsingBlock:'方法。所以最终代码如下:

    NSArray *lstAttributes = [conditionAttribute componentsSeparatedByString:cstrSystemUIConfigurationAttributeConditionSeparator],
        *lstValues = [conditionValue componentsSeparatedByString:cstrSystemUIConfigurationAttributeConditionSeparator],
        *lstValueTypes = [conditionValueType componentsSeparatedByString:cstrSystemUIConfigurationAttributeConditionSeparator];
    
    if([lstAttributes count] != [lstValues count] ||
       [lstAttributes count] != [lstValueTypes count]) return NO;
    
    NSMutableArray *lstConditions = [NSMutableArray new];
    for(uint i = 0; i < [lstAttributes count]; i ++)
    {
        SystemUIConfigurationAttributeCondition *condition = [SystemUIConfigurationAttributeCondition new];
    
        condition.conditionAttribute = [lstAttributes objectAtIndex:i];
        condition.conditionValue = [lstValues objectAtIndex:i];
        condition.conditionValueType = [lstValueTypes objectAtIndex:i];
    
        [lstConditions addObject:condition];
        FreeObject(&condition);
    }
    
    __block BOOL bResult = YES;
    [lstConditions enumerateObjectsUsingBlock:^(id obj, NSUInteger i, BOOL *stop) 
    {
        if([self checkCondition:[lstConditions objectAtIndex:i] forOwner:owner] == NO)
        {
            bResult = NO;
            *stop = YES;
        }
    }];
    
    FreeObject(&lstConditions);
    
    return bResult;
    

    此代码有效。

    如果有人能解释我的初始循环的行为,我将不胜感激。

答案 1 :(得分:0)

由于您在评论中提到如果您注释掉&amp; =操作,它会有效,我会将该行更改为:

bResult = bResult && [self checkCondition:condition forOwner:owner];

这是一个布尔AND,无论如何你真的打算在这条线上做。 &amp; =按位AND,它并不总是等效于布尔AND,因为任何非零值的计算结果为true。例如:

BOOL a = 1;
BOOL b = 2;

if (a && b) {
    NSLog (@"a && b is true"); // This line will execute
}
if (a & b) {
    NSLog (@"a & b is true");  // This line won't execute
}

由于在我们的条件中使用对象地址是很常见的,因此使用按位AND代替布尔值可能会产生错误。例如,如果从getCondition:fromOwner:返回一个对象地址,意味着它表示YES,并且该内存地址恰好是偶数,那么带有YES的按位AND将评估为NO,其中一个布尔AND将评估是的。

我对你的特定错误的原因最好的猜测是,按位-AND以某种方式导致缓冲区溢出,这会踩到你的i变量。如果该假设是正确的,那么切换到布尔AND也应该解决这个问题。