3

所以我一直在 Xcode4 中为一个具有多个集合视图(确切地说是 4 个)的应用程序工作

我有两个视图,一个底部“主”视图,其中包含一个填充屏幕的大型集合视图,以及一个较小的“抽屉”视图,可以从侧面拉出并包含三个狭窄的水平滚动集合视图堆叠一个在另一个之上。

我一直在使用cellforitematpath方法中的标签和 if 语句填充单元格。在 xcode 4 中,以及我在 xcode 4 中制作的一个项目,现在正在 xcode 5 中打开,这是可行的。我在底部收到一条警告(不是错误)control may reach end of non void function,但我仍然能够构建和运行并且它可以工作。

在 xcode 5 的一个新项目中,相同的代码将“控制可能到达非 void 函数的末尾”作为错误并且不允许构建和运行。这是无休止的令人沮丧。我不想返回一个单元格,除非有一个数组要填充单元格。我什至不知道'return nil'是什么意思。有人对如何关闭它有任何建议吗?

以下绝对不漂亮,输入风险自负:

- (UICollectionViewCell *) collectionView:(UICollectionView *)collectionView
                   cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    if (collectionView.tag == 0){
        static NSString *CellIdentifier = @"subjectCell";
        SubjectCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];

        AHSubject *cellSubject = [self.subjectsArray objectAtIndex:indexPath.row];

        [[cell subjectLabel]setText:cellSubject.name];

        return cell;
    }
    else if (collectionView.tag == 1){
        if ([categoryArray count] > 0) {
            static NSString *CellIdentifier = @"categoryCell";
            CategoryCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];

            AHCategory *cellCategory = [categoryArray objectAtIndex:indexPath.row];

            [[cell categoryLabel]setText:cellCategory.name];

            return cell;
        }
    }
    else if (collectionView.tag == 2){
        if ([subcategoryArray count] > 0) {
            static NSString *CellIdentifier = @"subcategoryCell";
            GroupCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];

            AHCardGroup *cellSubcategory = [subcategoryArray objectAtIndex:indexPath.row];

            [[cell subcategoryLabel]setText:cellSubcategory.name];

            return cell;
        }
    }
    else {
        if ([cardArray count] > 0) {
            static NSString *CellIdentifier = @"cardCell";
            CardCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];

            AHCard *cellCard = [cardArray objectAtIndex:indexPath.row];

            [[cell frontLabel]setText:cellCard.front];

            return cell;
        }
    }
    // return nil;
}
4

3 回答 3

5

只需取消注释return nil,就可以了。因为您的 finalelse处理所有情况,所以代码永远不会达到 that return nil,但是 Xcode 的分析器显然不够聪明,无法知道这一点。

编辑:可以在 Apple LLVM 5.0 - 警告 - 所有语言下的 Build Settings 中找到此设置。它属于“不匹配的返回类型”,过去默认为是,现在默认为是(视为错误)。您可以更改此设置以将其更改回警告。但我不会那样做。只需取消注释您return nil的就可以了。

我要指出的是,在没有返回值的情况下到达非 void 函数的末尾是一个错误,并且很可能导致崩溃,而返回 nil(例如)可能不会。考虑以下简单的示例:

- (NSString*) someString
{
    return nil;
}

// ... someplace elsewhere in the code:
NSString* aString = [self someString];
NSLog( @"aString = %@", aString );

这很好,您的输出将类似于:

aThing 返回 (null)

现在,如果您注释掉该返回,则:

- (NSString*) someString
{
    // return nil;
}

// ... someplace elsewhere in the code:
NSString* aString = [self someString];
NSLog( @"aString = %@", aString );

NSLog 调用将取消引用一些随机内存位置(我认为无论堆栈上发生了什么),您的应用程序几乎肯定会崩溃。

如果您有一个返回某种类型值的函数,它必须始终返回该类型的值。

Edit2(回应@Dave DeLong 的评论):好点,返回nil是一个错误,但我可能会争辩说,与简单地让函数以没有返回值结束相比,这是一个不那么严重的错误collectionView:cellForItemAtIndexPath: 事实证明这有点学术性,因为 OP 的代码是这样的return nil,无论如何,final 永远不会执行。

可以重写函数以避免警告并键入“return nil”,因此:

- (UICollectionViewCell *) collectionView:(UICollectionView *)collectionView    cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    id cell = nil;

    if (collectionView.tag == 0) {
        // Make a Subject cell
    }
    else if (collectionView.tag == 1) {
        // Make a Category cell.
    }
    else {
        // Make a Card cell.
    } 

    return cell;
}

...但最终结果与 OP 的原始代码相同(return nil未注释):该函数可以但不会返回 nil。

于 2013-09-20T03:07:33.333 回答
1

Xcode 在这里抱怨是对的。该代码中没有任何内容表明您的返回语句之一肯定会被调用。

  1. 如果您认为您的代码不应该到达最后一行,或者它会在程序的其他地方显示错误并且您不想尝试优雅地降级,您应该在这里放置一个断言(例如assert(false);),这会使您的程序崩溃而不是试图做一些你可能没有计划的事情。assert被标记为无返回函数,编译器知道您的代码在此行之后不需要返回值。

  2. 如果您认为您的代码可能会到达最后一行(取决于可能存在格式错误的传入数据),或者如果您希望在代码中其他地方出现错误的情况下优雅地降级,您应该决定在此处返回什么。返回nil可能不是最好的主意,因为UICollectionView不会喜欢这样的单元格(来自文档:“您不能从此方法返回 nil”)并且会引发异常,最终导致崩溃(所以最好自己崩溃在崩溃日志中跟踪会更容易)。当然,这种方法需要一些思考。

于 2013-09-20T05:07:51.673 回答
0

所以你只需要一个默认值。此方法实际上是用于根据表示对象中的某些状态来设置样式。

只需取消选中一个标签或选择默认视图以返回没有与您的值匹配的标签的事物。

于 2013-09-20T04:41:24.120 回答