1

我的教授给了我一个主要内容,我必须使用 Xcode 在 Objective-C 中制作 .h 和 .m 文件。我几乎完成了,但有两个警告我不知道如何摆脱,“未使用的表达式结果”。错误与我创建大小为 100 的数组的 init 方法有关。这里是 main 创建一个对象然后调用我不正确编码的方法的地方,这部分是我的老师给出的,我无法更改它:

//  main.m
//  ChutesAndLadders

#import <Foundation/Foundation.h>
#import "ChutesAndLadders.h"
int main(int argc, const char * argv[])
{   
    @autoreleasepool {

        ChutesAndLadders *cl = [[ChutesAndLadders alloc]init];
        [cl initBoard];
        [cl makeChutes:10];
        [cl makeLadders:10];

        int chutes=0; 
        int ladders=0;

        for(int i=0;i<cl.board.count;i++){
            NSString * cell = (NSString *)[cl.board objectAtIndex:i];
            int additionalSpaces = (int)[cl addToMove:cell];
            if(additionalSpaces>0)
                ladders++;
            else if (additionalSpaces<0)
                chutes++;
        }
        [cl printBoard];
    }
    return 0;
}

这是我的方法的相关部分:错误来自上面的“initBoard”方法和下面的“initWithCapacity”行。我知道这两个警告描述的是同一个错误。下面的代码是我的,所以我可以更改它,与上面不同。

@synthesize board = _board;

-(id) initBoard
    if((self = [super init]){
        [board intiWithCapacity: 100];
        for(int i = 0; i < 100; i++){
            [board addObject:@""];       
        }
    }
return self;
}

这是我在 .h 文件中声明“板”的相关代码:

@interface ChutesAndLadders : NSObject{
    @private

    NSMutableArray * board;
}
@property (readwrite, retain) NSMutableArray *board;

-(id) initBoard;

我尝试了很多语法上的小改动,但无济于事。请不要直接告诉我解决方案,但我认为我只需要向正确的方向轻推或推动,一旦我知道解决方案,我将发布解决方案。

伪解决方案:

@synthesize board=board;

-(void) initBoard{
    _board = [board initWithCapacity: 100];
    for(int i =0; i < 100; i++){
        [_board addObject:@""];
    }
}

这消除了其中一个警告,但我的程序运行不正常,所以我还有其他方法要做。虽然这个具体问题已经得到解决,但我对它现在的工作方式有了更好的了解。

实际解决方案

@synthesize board=_board;

-(void) initBoard{
    _board = [NSMutableArray arrayWithCapacity:100];
    for(int i =0; i < 100; i++){
        [_board addObject:@"   "];
    }
}

这是最终根据Hermann工作的方法。我发誓我尝试过一次但它没有用,所以我一直在玩并改变一些东西(把它搞得更糟),然后最终又回到了这个,它当然奏效了。Xcode 的谎言有时会激怒我。

4

4 回答 4

2

编辑因为起初我忽略了一些东西:

只需使用:

ChutesAndLadders *cl = [[ChutesAndLadders alloc]initBoard];

因为在 initBoard 中你[super init]无论如何都在打电话。

你的教授想欺骗你吗?不看所有代码就很难说。您正在合成具有 iVar _board 的属性板。这意味着您可以通过self.boardor[self board]或分别访问它的 getter 或 setter [self setBoard: ...]

但在 initBoard 方法中,它的访问方式不同:

[board intiWithCapacity: 100];

尽管我们看不到板实际分配在哪里,并且没有使用 initWithCapacity 方法的结果,但我问自己board实际上是什么。它不是属性(即 self.board 等),也不是 iVar(即_board)。显然只是board指您声明的私有 iVar。但

@synthesize board = _board;

创建一个具有相同类型名称的 iVar _board(NSMutableArray*)。因此,在您的方法中,board不同于_board.

尽管我现在第三次编辑这个,我仍然没有得到它。.m 文件是老师给的,你必须创建一个匹配的 .h 文件,对吗?在这种情况下,你应该去

@private
NSMutableArray * _board;

好吧,无论如何这都是自动完成的,但是用“_”编写它可以避免创建类似的命名 iVar,从而避免可能的错误。

背景 AFAIK:理论上甚至实际上 init 可能会创建一个与 alloc 创建的实例不同的实例。因此,您应该始终使用 init 的返回值。

一般来说——独立于围绕对象初始化的奇怪的objective-c符号——当一个方法返回一个值时,然后

[object method];

语法正确,运行良好,除返回值外的所有内容均未使用。这就是您的警告信息的全部内容。即使你将它分配给一个虚拟对象,比如

SomeClass *someObject = [object method];

你会得到'someClass'是一个未使用的变量的警告。

最后编辑:你快到了。但是,这是当前版本的 Obj-C 的快捷方式,不适用于旧版本:.h 文件:

@interface ChutesAndLadders : NSObject

@property (readwrite, retain) NSMutableArray *board;

-(void) initBoard;
@end

.m 文件:

// omitting @synthesize forces the compiler to autosynthesize. In that case it is named "_board"

    -(void) initBoard
        _board = [NSMutableArray arrayWithCapacity: 100]; // this implies the alloc
        for(int i = 0; i < 100; i++){
            [_board addObject:@""];       
        }
    }
于 2013-02-19T09:12:43.983 回答
1

你正在返回一些你不使用的东西。还阅读了在 Objective-C 中编写正确的构造函数/初始化对象。

于 2013-02-19T09:05:09.940 回答
0

正如赫尔曼所说,你应该这样做

ChutesAndLadders *cl = [[ChutesAndLadders alloc]initBoard];

然后在你的 initBoard 方法中

self.board = [NSMutableArray alloc] intiWithCapacity: 100];
于 2013-02-19T09:16:04.733 回答
0

您没有遵循标准的 Objective-C 约定,这会让您陷入困境。

你有一个实例变量板。Objective-C 约定是所有实例变量都应该以下划线字符开头。

你有一个属性板,@synthesize board = _board。合成创建一个带有下划线字符的实例变量,名为 _board。现在你有两个实例变量:board 和 _board。其中之一,_board,是支持 board 属性的实例变量。另一个,董事会,与董事会财产完全无关。

然后在某个地方,你有一个看起来无害但致命的声明板 = 随便什么。分配给那个完全无用的实例变量板。不是_board,而是board。如果您编写了 _board,那么您将遵循 Objective-C 约定:使用高度可见的名称分配给实例变量。或 self.board 这将是财产。

而 [board initWithCapacity:100] 什么也没做。首先,因为 board 实例变量(与 board 属性或 _board 实例变量完全无关)尚未分配。是零。将 initWithCapacity 发送到 nil 什么也不做。将 addObject 发送到 nil 也无济于事。

于 2014-07-31T16:55:32.737 回答