Objective-C"消息" - 阅读它的正确方法是什么?

bob*_*obo 8 object objective-c message-passing

您可以在objective-c中声明一个方法,并基本上将每个参数命名为两次.

我觉得这很强大,但我还不确定如何使用它......

当John Greets Kelly:

[ p Greet:"John" toPerson:"Kelly" greetWith:"hey babe" ] ;

关于它的一些东西不能自然地阅读.我不确定这是一个经验丰富的Objective-c程序员是如何写出"消息"的.

有人可以解释每个参数的两个名称的原因,并可能是一个更有用的例子,说明如何有效地使用它来在程序中加入意义?

还有什么困扰我,这是第一个参数的名称基本上与' 消息 ' 的名称相同.你如何通过编写有意义且易于理解的方法/'消息名称'来解决这个问题?

#import <Foundation/Foundation.h>

@interface Person : NSObject
{
}

-(void)Greet:(char*)from toPerson:(char*)to greetWith:(char*)greeting ;

@end

@implementation Person

-(void)Greet:(char*)from toPerson:(char*)to greetWith:(char*)greeting ;
{
  printf( "%s says %s to %s\n", from, greeting, to ) ;
}

@end



int main (int argc, const char * argv[])
{
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];


  Person * p = [ Person alloc ] ;

  [ p Greet:"John" toPerson:"Kelly" greetWith:"hey babe" ] ;
  [ p Greet:"Kelly" toPerson:"John" greetWith:"get bent" ] ;

  [ p release ] ;



  [pool drain];
  return 0;
}

Jed*_*ith 20

首先要做的事情是:作为一个风格的笔记,把你的大括号放在一起:

[ Person alloc ]
Run Code Online (Sandbox Code Playgroud)

应该

[Person alloc]
Run Code Online (Sandbox Code Playgroud)

我还注意到你忘记在分配它时初始化Person,你应该使用:

Person *p = [[Person alloc] init];
Run Code Online (Sandbox Code Playgroud)

了解如何声明方法只需要一点时间.检查框架如何命名其方法是有用的.对于您的具体示例,我认为您是过度工程.你正在寻找这样的东西:

Person *john = [[Person alloc] initWithName:@"John"];
Person *kelly = [[Person alloc] initWithName:@"Kelly"];

[john greetPerson:kelly withGreeting:@"Hey babe."];
[kelly greetPerson:john withGreeting:@"Get bent."];
Run Code Online (Sandbox Code Playgroud)

请注意,我没有资本化ggreetPerson,无论是.这是Objective-C的风格惯例.

不要忘记一个对象有自己的身份,所以你很少需要在与某人交谈之前指示一个对象(意味着代表一个人).当你写一条消息时,它应该像英语一样.当你进入多个论点 - 诚然,罕见 - 开始用逗号思考:

[john sendEmailToPerson:kelly withSubject:subject body:body attachments:nil];
Run Code Online (Sandbox Code Playgroud)

看看它是如何流动的?即使这样做还有一些不足之处,我也没有掌握这一点.给它点时间.

关于这一点的一个非常有用的文件是Apple的Cocoa编码指南.


另外,让自己脱离C陷阱.以下是我编写整个程序的方法(我正在介绍一大堆概念,所以不要指望理解所有这些概念):

#import <Foundation/Foundation.h>

@interface Person : NSObject {
    NSString *name;
}

@property (copy) NSString *name;

- (id)init;
- (id)initWithName:(NSString *)nm;
- (void)greetPerson:(Person *)who withGreeting:(NSString *)grt;

@end

@implementation Person
@synthesize name;

- (id)init {
    if (self = [super init]) {
        name = @"James Bond";          // not necessary, but default
    }                                  // values don't hurt.
    return self;
}
- (id)initWithName:(NSString *)nm {
    if (self = [self init]) {
       name = [nm copy];
    }
    return self;
}

- (void)greetPerson:(Person *)who withGreeting:(NSString *)grt {
    NSLog(@"%@ says '%@' to %@", self.name, grt, who.name);
}

- (void)dealloc {
    [name release];
    [super dealloc];
}

@end

int main(int argc, const char * argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    Person *john = [[Person alloc] initWithName:@"John"];
    Person *kelly = [[Person alloc] initWithName:@"Kelly"];

    [john greetPerson:kelly withGreeting:@"StackOverflow is great, isn't it?"];
    [kelly greetPerson:john withGreeting:@"Weren't we supposed to flirt?"];

    [john release];
    [kelly release];

    [pool drain];
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这段代码完全没有经过测试,因此如果它顺利运行,我会留下深刻的印象.

  • Apple的样式指南建议您不要在方法名称的后续部分使用"和".(从您刚刚链接的文档:"不要使用"和"链接作为接收者属性的关键字.")因此选择器应该只是`sendEmailToPerson:withSubject:body:attachments:`. (3认同)
  • @Chuck:看到了?告诉你我不是专家.编辑出来. (2认同)
  • 好答案.您在代码中添加了一个注释,但未提及:选择器的第一部分不应大写.所以你会[john greetPerson]而不是[john GreetPerson:].我知道它的挑剔,但Objective-C程序员非常讲究语法和风格指南!首都Greet非常Javaish. (2认同)