【问题标题】:Creating and looping through array of bools创建和循环布尔数组
【发布时间】:2012-04-18 01:43:34
【问题描述】:

我正在创建一个拼图应用程序。当每块被触摸时,如果将其放在正确的位置,则将布尔 (droppedInPlace) 分配为 YES,如果将其放在错误的位置,则分配 NO。然后我想我需要创建一个包含 40 个布尔值(拼图块的数量)的数组,这些条目中的每一个最初都将设置为 NO。

然后使用replaceObjectAtIndex 将这个布尔值 (droppedInPlace) 插入到一个数组中。然后我想遍历这个数组。如果所有条目都是 true/yes/1,那么拼图就完成了,我将运行一些代码。

我在执行此操作时遇到了一些问题。我不知道如何在上面编写我的想法。以下是我的代码:

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
UIView *touchedView = [touch view];
// filename to be read from
NSString *filePath = [[NSBundle mainBundle]
                      pathForResource: 
                      @"jigsawHomeCenterPoints" 
                      ofType:@"plist"];
// array of cgpoints in string format
NSArray *jigsawHomeCentersArray = [NSArray arrayWithContentsOfFile:filePath];
// the tag number of the selected image
int tag = touchedView.tag;
NSLog(@"tag: %i", tag);
// says that the piece has not been dropped in it's holder
bool droppedInPlace = NO;
// if what has been touched is part of the array of images
if ([imagesJigsawPieces indexOfObject:touchedView] != NSNotFound) {
    // preparing new snap-to-center position
    // using (tag-1) as an index in the HomeCentersArray corresponds to where the image should be placed
    // this was a conscious decision to make the process easier
    CGPoint newcenter = CGPointFromString([jigsawHomeCentersArray objectAtIndex:tag-1]);
    // the location of the current touch
    CGPoint location = [touch locationInView:self.view];
    // call the animate method upon release
    [self animateReleaseTouch:touchedView withLocation:location];
    // setting a proximity range - if it is within this 80x80 area the image will snap to it's corresponding holder (HomeCenter)
    if (location.x > newcenter.x-40 && location.x < newcenter.x+40 
        && location.y > newcenter.y-40 && location.y < newcenter.y+40) {
        touchedView.center = newcenter;
        touchedView.alpha = 1.0;
        droppedInPlace = YES;
    } else {
        touchedView.alpha = 0.5;
        droppedInPlace = NO;
    }
    NSLog(@"True or false: %i", droppedInPlace);
[self checkJigsawCompleted:droppedInPlace withTag:tag];
}
}

还有校验功能:

-(void) checkJigsawCompleted:(BOOL)inPlace withTag:(NSInteger)tag {
NSMutableArray *piecesInPlace;
[piecesInPlace replaceObjectAtIndex:tag-1 withObject:[NSNumber numberWithBool:inPlace]];
//code to loop through array - check if all entries are true/yes/1
//if so, jigsaw is completed - run some other code
//else, do nothing
}

【问题讨论】:

    标签: objective-c ios arrays boolean


    【解决方案1】:

    请注意,您的 piecesInPlace 数组未在方法 checkJigsawCompleted 中初始化,将在下一行崩溃。

    假设它用正确的值初始化,检查所有值是否为真的方法很简单:

    for (NSNumber *boolNumber in piecesInPlace) {
        if (![boolNumber boolValue])
           return false;
    }
    
    return true;
    

    编辑:或更好:

    return ![piecesInPlace containsObject:[NSNumber numberWithBool:NO]];
    

    【讨论】:

      【解决方案2】:

      您想知道如何遍历数组吗?您可以使用for(;;) 循环或for(.. in ..) 循环,或者,我最喜欢这种事情:-enumerateObjectsUsingBlock:

      __block jigsawIsComplete = true;
      [piecesInPlace enumerateObjectsUsingBlock: ^(id obj, NSUInteger i, BOOL* stop)
          {
              jigsawIsComplete = jigSawIsComplete && [obj boolValue];
              *stop = !jigsawIsComplete;
          }];
      

      【讨论】:

        【解决方案3】:

        所以,有几件事。首先,您将根据拼图的标签替换这个piecesInPlace 可变数组中的对象,看起来像这样。但是,您永远不会设置这些视图的标签。所以,这一行:

        int tag = touchedView.tag;
        

        将始终为 0。更糟糕的是,您的 replaceObjectAtIndex:tag-1 位将尝试访问不合法的数组的 -1 索引(此时,但一旦 Apple 公开了一些更改)合法。

        只要循环遍历数组并检查真值,我建议使用该方法

        - (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block
        

        使用这个,只要在数组中找到 NO 值,就可以将停止指针设置为 YES,枚举将结束。只要停止为否,您只想继续枚举。如果你不停地通过你的数组,所有的值都是 YES。

        【讨论】:

        • 我实际上已经在我的故事板中给出了所有图像标签,从 1 到 40。使用replaceObjectAtIndex:(tag-1) 有意义吗?这些括号能确保我不会尝试访问 -1 索引吗?
        • 想想吧。如果第一个标签为 0,括号将如何防止标签 - 1 为 -1?当然,如果你在 IB 中手动设置标签,只需从最低标签 1 开始就可以了。
        • 抱歉,我想我们的电线在那儿交叉了——虽然你的意思是别的。我的最低标签确实是 1。
        • 不用担心。但无论如何,您的问题的答案是 enumerateObjectsUsingBlock:
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-11-02
        • 2015-11-08
        • 2017-11-20
        • 2016-07-13
        • 1970-01-01
        • 1970-01-01
        • 2013-10-09
        相关资源
        最近更新 更多