我的申请中有以下代码:
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”运算符,但没有任何正常工作。循环仍然无法停止。
以前有人遇到过同样的问题吗?
答案 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个被破坏。
所以我决定将我的初始循环分成两部分:
首先是通常的“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也应该解决这个问题。