0

我对Objective C非常陌生,并且正在从事一个项目,并且我正在努力解决传递引用问题,这在我的代码中可能很明显。如果有人可以就我的代码为我分解它,我将不胜感激。

@interface Player : NSObject
{

}

//@property
@property (nonatomic, readwrite) NSString* name;
@property (nonatomic, readwrite) NSInteger *humanPoints;
@property (nonatomic, readwrite) NSInteger *computerPoints;
@property (nonatomic, readwrite) BOOL isWin;
@property (nonatomic, readwrite) BOOL isLoss;
@property (nonatomic, readwrite) BOOL isPoints;
@property (nonatomic, readwrite) NSInteger rollAgain;
//Methods
-(id) init;
-(void) RollFirstDie: (NSInteger) firstDie andSecondDie: (NSInteger) secondDie andThirdDie: (NSInteger) thirdDie;
-(NSInteger) GetRandomRoll;
-(BOOL) DoRoll; 


@end

用它的.m

#import "Player.h"


@implementation Player

@synthesize name;
@synthesize humanPoints;
@synthesize computerPoints;
@synthesize isWin;
@synthesize isLoss;
@synthesize isPoints;
@synthesize rollAgain;

-(id) init
{
    self = [super init];

    if (self!=NULL)
    {
        name = @"human";
        humanPoints = 0;
        computerPoints = 0;

    }
    return self;
}

-(void)RollFirstDie: (NSInteger) firstDie andSecondDie: (NSInteger) secondDie andThirdDie: (NSInteger) thirdDie
{

    firstDie = arc4random()% 6+1;
    secondDie = arc4random()% 6+1;
    thirdDie = arc4random()% 6+1;

}

-(NSInteger) GetRandomRoll
{


    die1 = firstDie;
    die2 = secondDie;
    die3 = thirdDie;

    return die1, die2, die3;
}

-(BOOL) DoRoll
{
    NSLog(@"Human Roll Dice?[Y/N] ");
    scanf(" %ld", &rollAgain);

    return rollAgain;
}

我遇到的最大麻烦是第二个.h/.m:

#import <Foundation/Foundation.h>
#import "Player.h"

@interface DiceGame : NSObject
{
    NSInteger die1;
    NSInteger die2;
    NSInteger die3;

    //Player* human
    //Player* cpu
    BOOL rollAgain;
}


//Methods
-(id) init;
-(void) Play;
-(void) CheckRollConditions;
-(void) ResetDice;
-(void) DisplayWinner;
-(void) TakeTurn;

@end

.m

#import "DiceGame.h"

@implementation DiceGame

-(id) init
{
    self = [super init];

    if (self!=NULL)
    {
        die1 = 0;
        die2 = 0;
        die3 = 0;

    }
    return self;
}

-(void) Play
{
    [self TakeTurn];
    if (name isEqual @"human")
    {
        [self RollFirstDie: firstDie andSecondDie: secondDie andThirdDie: thirdDie];
        [self CheckRollConditions];
        if (rollAgain == 1)
        {
            [self RollFirstDie: firstDie andSecondDie: secondDie andThirdDie: thirdDie]
            [self CheckRollConditions];
        }
        name = @"computer";
    }
    [self ResetDice ];
    while (computerPoints == 0)
    {
        [self RollFirstDie: firstDie andSecondDie: secondDie andThirdDie: thirdDie]
        [self CheckRollConditions];
        while (computerPoints == humanPoints)
        {
            [self RollFirstDie: firstDie andSecondDie: secondDie andThirdDie: thirdDie]
            [self CheckRollConditions];
        }
    }

    [self DisplayWinner ];


    [self GetRandomRoll];


}
-(void) CheckRollConditions
{
    //Three of a Kind
    if ((die1 == die2) && (die1 == die3))
    {
        NSLog(@"You got 3 of a kind, you win!");

    }
    //Two of a Kind
    else if ((die1 == die2) || (die2 == die3) || (die1 == die3))
    {
        if (die1 == die2)
        {
            if (Player.name isEqual @"human")
            {
                humanPoints = die3;
            }
            else
            {
                computerPoints = die3;
            }


        }
        else if (die1 == die3)
        {)
            if (name isEqual @"human")
            {
                humanPoints = die2;
            }
            else
            {
                computerPoints = die2;
            }
        }
        else
        {
            if (name isEqual @"human")
            {
                humanPoints = die1;
            }
            else
            {
                computerPoints = die1;
            }
        }
        if (name isEqual @"human")
        {
            NSLog(@"You got a pair, your score is: %ld", humanPoints);
        }
        else
        {
            NSLog(@"Computer got a pair, their score is: %ld", computerPoints);
        }

    }
    //Lose Sequence
    else if (((die1 != die2) && (die1 != die3) && (die2 != die3)) && ((die1 <= 3) && (die2 <= 3) && (die3 <= 3)))
    {
        NSLog(@"Game Over, %@ Lose!", name);

    }
    //Win Sequence
    else if (((die1 != die2) && (die1 != die3) && (die2 != die3)) && ((die1 > 3) && (die2 > 3) && (die3 > 3)) && ((die1 <= 6) && (die2 <=6) && (die3 <= 6)))
    {
        NSLog(@"Congratulations! %@ Wins!", name);

    }

    //No win or lose
    else
    {
        while (name isEqual @"human")
        {
            NSLog(@"You did not get a sequence or a pair");
            NSLog(@"Human, roll again?[y/n]");
            scanf("%ld", &rollAgain);break;
        }

    }


}
-(void) ResetDice
{
    die1 = 0;
    die2 = 0;
    die3 = 0;
}
-(void) DisplayWinner
{
    if (computerPoints > humanPoints)
    {
        NSLog(@"Computer had a higher score");
    }
    else
    {
        NSLog(@"Human had a high score");
    }
}
-(void) TakeTurn
{

        if ([name isEqual: @"human"])
        {
            [self RollFirstDie: firstDie andSecondDie: secondDie andThirdDie: thirdDie]
            NSLog(@"Rolling...");
            NSLog(@"You rolled: ");
            NSLog(@"%ld, %ld, %ld", die1, die2, die3);

        }
        else
        {

            {
                [self RollFirstDie: firstDie andSecondDie: secondDie andThirdDie: thirdDie]
                NSLog(@"Rolling...");
                NSLog(@"Computer rolled: ");
                NSLog(@"%ld, %ld, %ld", die1, die2, die3);
            }
        }

}


@end

主要:

#import <Foundation/Foundation.h>
#import "DiceGame.h"


int main(int argc, const char * argv[])
{
    @autoreleasepool
    {
        DiceGame* roll = [[DiceGame alloc] init];


        [roll Play];


    }
    return 0;
}

所以发生的事情是 DiceGame.m 无法识别 Player 类中的任何内容。我知道我想要代码做什么,但我正在努力实现它。(因为这已经是一篇很长的帖子,所以我省略了一些后来我没有遇到问题的方法)

编辑:谢谢你们的帮助,我已经用完整的代码更新了这个,但是你是对的,它没有编译,这就是我现在需要的帮助。Pass By Reference 问题并没有我最初想象的那么严重。我相信我现在遇到的错误是同一问题的一部分: 1. 使用未声明的已识别“variableName”(die1/die2/die3 等)。我让它们在一个单独的方法中定义,但我认为这不应该是一个问题?不知道我是错的还是我错过了一些重要的东西

  1. 'DiceGame' 没有可见的@interface 声明选择器'GetRandomRoll'(和其他)

我认为只有一个类可以从 NSObject 继承,但我似乎不知道如何修复我的代码以使其工作

4

3 回答 3

0

在 Objective-C 中,我们为所有对象使用指针,因此当您传递对象时,您通过引用传递它们。

因此,当您执行类似NSString *str = @"hi!";创建指向NSString对象的指针的操作时。现在,每当您str作为方法参数传递时,您都是通过引用传递它。

我看到你也在尝试做同样的事情NSInteger,但是 NSIntegers 不是对象,但它们只是类型定义int为 C 中的数据类型,因此它们是按值传递的,你不应该使用星号。您可以这样做:NSInteger value = 4;密切关注某事物是对象还是只是原始类型或结构,这一点很重要。

我还注意到几个编码约定问题:

  • 当你这样做时,self = [super init];你可以if(self)改为使用它(我认为 NULL 的工作方式相同,但在 ObjC 中我们使用nil)。
  • 方法名称是驼峰式命名而不是 TitleCase;我们为类名保存 TitleCase

希望这能让你解决问题!

于 2016-02-23T01:19:39.200 回答
0

除了通过引用您的问题进行调用之外,还有更多问题,但尚不清楚发布的代码是否是您的实际代码,因为它似乎无法编译。所以我只是通过引用来解决电话,希望它有所帮助。

Objective-C 确实以与 C 相同的方式通过引用调用,这意味着它不直接支持它——它是一个自己动手的构造:

  1. 当你调用一个函数时,你传递了一个变量的地址
  2. 在函数声明中,您将参数类型声明为指向参数类型的指针;和
  3. 在函数体中,您使用间接访问变量

因此,对于您的掷三个骰子方法,该方法将是(注意:所有代码都直接输入答案,预计很少有错别字)

-(void) rollFirstDie:(NSInteger *)firstDie  // parameter type is
        andSecondDie:(NSInteger *)secondDie //  pointer to NSInteger
         andThirdDie:(NSInteger *)thirdDie
{
   *firstDie = arc4random_uniform(6) + 1;  // 1) must use indirection, *firstDie,
   *secondDie = arc4random_uniform(6) + 1; // to access variable
   *thirdDie = arc4random_uniform(6) + 1;  // 2) arc4random_uniform is better than
                                           // using modulus (%), see documentation
}

电话是:

[aPlayer rollFirstDie:&firstDie  // pass the address (&) of the variable
         andSecondDie:&secondDie
          andThirdDie:&thirdDie];

用于返回多个值的 DIY 引用调用的另一种方法是使用 a struct, astruct是一种按值传递的简单记录类型。因此,例如,您可以定义:

typedef struct
{
   NSInteger firstDie;
   NSInteger secondDie; 
   NSInteger thirdDie;
} ThreeDice;

表示您的三个骰子,然后定义您的 roll 方法以返回此类型的值:

-(ThreeDice) rollThreeDice
{
   ThreeDice diceSet;
   diceSet.firstDie = arc4random_uniform(6) + 1;  // use <struct>.<field> to
   diceSet.secondDie = arc4random_uniform(6) + 1; // access each element
   diceSet.thirdDie = arc4random_uniform(6) + 1;
   return diceSet; // return the value
}

你的电话变成:

ThreeDice rollOne;
rollOne = [myPlayer rollThreeDice];

正如您所看到的,使用 astruct可以避免使用地址 ( &)、声明指针 ( NSInteger *) 和间接 ( *firstDie)。

高温高压

于 2016-02-22T18:36:20.970 回答
0

如果这种方法:

-(void)RollFirstDie: (NSInteger) firstDie andSecondDie: (NSInteger) secondDie andThirdDie: (NSInteger) thirdDie

与您在此处调用的方法相同:

[self RollFirstDie: (NSInteger*) firstDie andSecondDie: (NSInteger*) secondDie andThirdDie: (NSInteger*) thirdDie];

这不是 Objective-C 中的正常方法,(NSInteger*) firstDie将 firstDie 中的任何内容转换为 NSInteger 的指针,如果您调用相同的方法,除非您这样做,否则它不会编译*(NSInteger*) firstDie(假设 firstDie 是 NSInteger)

但正如我所说,这可能不是你想要的,如果 firstDie 只是一个 NSInteger,你应该简单地做:

[self RollFirstDie: firstDie andSecondDie: secondDie andThirdDie:thirdDie];

在这种情况下,firstDie、secondDie 和 thirdDie 将按值传递,因为 NSInteger 是 objc 中的原始类型。如果你想通过引用传递,你应该使用NSNumber*.

希望这可以帮助。

于 2016-02-22T01:56:58.173 回答