【问题标题】:OOP In Objective-CObjective-C 中的 OOP
【发布时间】:2012-11-26 06:09:35
【问题描述】:

我熟悉 OOP,因为我已经用 Java 编码了一段时间,但是我在 Objective-C 中遇到了(语法?)问题。我一直在看这里的其他帖子,但到目前为止没有任何帮助。

我有一个名为“Play_Name.m”的类,它有一个方法可以在触摸按钮时设置玩家名称,还有另一个方法可以获取名称并返回一个字符串,(NSString*)get_name。我还有另一个名为“Play_ChooseChar.m”的类,它应该显示通过调用 get_name 函数输入的名称。

当我在“Play_Name”(它的所有者)中调用它时,get_name 返回正确的名称,但是当我在“Play_ChooseChar”中调用它时,它返回(null)。

//Play_Name code below

#import "Play_Name.h"

@interface Play_Name ()

@end

@implementation Play_Name

@synthesize playerName;
@synthesize textName;


-(IBAction)set:(id)sender {

[self setPlayerName:(self.textName.text)];

if([self.textName.text length] <= 0) {
    playerName = @"Player";
    NSLog(@"YOUR NAME: %@", playerName);
}

NSLog(@"YOUR NAME: %@", playerName);

}

//...........

@end





//Play_ChooseChar code below

#import "Play_ChooseChar.h"
#import "Play_Name.h"

@interface Play_ChooseChar ()

@end

@implementation Play_ChooseChar

@synthesize display_name;
@synthesize playname;
@synthesize boy;
@synthesize girl;
@synthesize isGirl;
@synthesize isBoy;

bool isGirl = FALSE;
bool isBoy = FALSE;

-(void)theName {

Play_Name *pN = [[Play_Name alloc] init];
[pN setPlayerName: pN.playerName];
NSLog(@"NAME: %@", pN.playerName);

self.display_name.text = pN.playerName;
//display_name.text = @"test";

[pN release];

//............

@end

所以当我运行它并输入我的名字时,来自“Play_ChooseChar”的打印语句返回'NAME: (null)'

【问题讨论】:

    标签: objective-c oop instance


    【解决方案1】:

    开幕演讲:您似乎在抛开 Objective-C 约定。 Getters 不应该指得到的行为——所以你应该实现name,而不是get_name,并且几乎你会看到的唯一动词是'is',在isValid ala NSTimer 的意义上。 Objective-C 也使用驼峰式大小写,以小写字符开头,所以player_name 应该是playerName。同样,您的类应该有一个三个字母的前缀(因为 Objective-C 不做命名空间)并且也是驼峰式的,例如ATPPlayName.

    抛开讲义,这个:

    Play_Name *play_name = [[Play_Name alloc] init];
    

    创建一个全新的Play_Name 实例。它与您在其他地方使用的任何实例都不相同。该实例尚未附加名称。所以当你在下一行询问它的名字时,它是nil

    【讨论】:

    • 不可避免的吹毛求疵:公平地说,setter 通常在其中包含动词 - 由属性生成的方法通常采用 和 set 的形式。不过,这确实归结为个人选择。
    • @Xono 你说的很对; setter 应该有动词,只有 getter 不应该。我将编辑答案,但我认为在您的评论已修复后,如果没有明确承认我的错误,这样做是不公平的。
    • 那我将如何获得该名称值?它必须取自“Play_Name”实例的方法调用,不是吗?
    • @Tommy 公平地说,有些 getter 写成 isSomething,所以有些 getter 也有动词。
    • @atpietr 大概你的视图控制器会有一个实例变量,它是对 Play_Name 实例的引用。然后你会在同一个实例上做这两个动作。
    【解决方案2】:

    您没有真正显示足够的代码来确定问题。但是,我建议使用属性而不是遵循您自己的命名约定的方法。例如:

    @interface Player: NSObject
    @property NSString* name;
    @property NSString* character;
    @end
    

    上面定义了一个类Player,其属性为namecharacter。 Xcode 将生成“支持”这些属性的适当访问器方法和实例变量。请参阅language reference for more details

    【讨论】:

    • 所以这些是在“Player_Name”中声明的。如何在“Play_Character”中访问它们?
    • 您只需要像任何其他面向对象语言一样的关系。虽然,您似乎正在尝试为听起来应该是属性的数据创建类。为什么要创建一个类Player_Name?而不是具有name 属性的Player 类?
    • 我认为除了我自己之外,我的类命名约定让所有人都感到困惑。
    【解决方案3】:

    您应该创建属性,xcode 会自动为您创建 getter 和 setter。

    Have a look here:

    【讨论】:

      【解决方案4】:

      抛开设计和代码约定: 当你创建一个新的 Play_Name 实例时,它的 get_name 显然会返回 nil,因为在调用 get_name 之前代码中没有任何地方调用过 set_name。

      您应该首先执行以下操作: [play_name set_name:@"john"];

      并且,假设您的 set_name 方法正确实现,[play_name get_name] 应该返回正确的值。

      我支持其他建议使用属性的人,因为它可以为您处理大多数内存管理的细微差别。您可以在此处阅读有关此内容的更多信息: Objective-C: Declared Properties

      【讨论】:

      • 好的,所以在“Play_Name.h”中我有:'@property (readwrite, retain) NSString *player_name;'我在“Play_Name.m”中合成了它。我在 Play_Name 中进行“设置”,在 Play_Character 中进行“获取”?
      • 我不确定你想在哪里调用'set'......这完全取决于你的软件设计:只要你已经有了玩家的姓名信息,你就会调用'set',我猜.当您想创建一个具有某些默认名称的新角色时,这可以从一些高级控制器类(如 ViewController)中完成,甚至可以从角色类中完成。可能有很多地方可以从...调用“setName”。
      猜你喜欢
      • 2013-08-14
      • 1970-01-01
      • 2010-12-25
      • 1970-01-01
      • 1970-01-01
      • 2018-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多