2009-11-08 31 views
7

Bạn có thể khai báo một phương thức trong mục tiêu-c và tên mỗi tham số hai lần, về cơ bản.Mục tiêu-C "tin nhắn" - cách thích hợp để đọc nó là gì?

tôi nhận được ý kiến ​​cho rằng đây là mạnh mẽ, nhưng tôi không hoàn toàn chắc chắn làm thế nào để sử dụng nó chưa ...

Khi John Greets Kelly:

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

Something về nó doesn không đọc một cách tự nhiên. Tôi không chắc đó có phải là một lập trình viên khách quan có kinh nghiệm viết ra "thông điệp" đó không.

Ai đó có thể giải thích lý do hai tên cho mỗi thông số và có thể là ví dụ hữu ích hơn về cách sử dụng hiệu quả để đặt ý nghĩa trong chương trình?

Điều gì đó làm phiền tôi và đó là tên của thông số đầu tiên về cơ bản giống với tên của thông báo ''. Làm thế nào để bạn giải quyết bằng văn bản phương thức có ý nghĩa và dễ hiểu/'tên thông điệp'?

 
#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; 
} 

+0

Về chỉnh sửa: Tôi đã nhấp vào ghi chú do nhầm lẫn khi tôi đến yêu thích, và sau đó nó sẽ không cho phép tôi đảo ngược nó (lỗi lạ?). Tôi đã chỉnh sửa câu trả lời của bạn để tôi có thể trao đổi nó. –

Trả lời

20

Trước tiên: như một lưu ý phong cách, mang niềng răng của bạn với nhau:

[ Person alloc ] 

nên

[Person alloc] 

Tôi cũng lưu ý rằng bạn đang quên để khởi Person khi bạn phân bổ, bạn nên sử dụng:

Person *p = [[Person alloc] init]; 

Nhận cảm giác về cách khai báo các phương thức mất một chút thời gian. Kiểm tra cách khuôn khổ đặt tên cho các phương thức của nó là hữu ích. Đối với ví dụ cụ thể của bạn, tôi nghĩ rằng bạn đang overengineering. Bạn đang tìm kiếm một cái gì đó như thế này:

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

[john greetPerson:kelly withGreeting:@"Hey babe."]; 
[kelly greetPerson:john withGreeting:@"Get bent."]; 

Lưu ý rằng tôi đã không viết hoa g trong greetPerson, một trong hai. Đó là một quy ước phong cách của Objective-C.

Đừng quên rằng một đối tượng có bản sắc riêng của nó, vì vậy hiếm khi bạn cần hướng dẫn một đối tượng (có nghĩa là đại diện cho một người) trước khi nó nói chuyện với ai đó. Khi bạn viết một tin nhắn, nó nên đọc như tiếng Anh. Khi bạn tham gia nhiều đối số - phải thừa nhận rằng, hiếm - bắt đầu suy nghĩ bằng dấu phẩy:

[john sendEmailToPerson:kelly withSubject:subject body:body attachments:nil]; 

Xem luồng đó như thế nào? Và ngay cả điều đó để lại một số mong muốn, tôi cũng chưa có chủ nhân này. Cho nó thời gian.

Một tài liệu rất hữu ích về điều này là của Apple Coding Guidelines for Cocoa.


Ngoài ra, hãy thoát ra khỏi bẫy C.Đây là cách tôi muốn viết toàn bộ chương trình của bạn (tôi giới thiệu một chiếc ghe chở khái niệm, do đó, không mong đợi để hiểu tất cả của nó):

#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; 
} 

Mã này là hoàn toàn chưa được kiểm tra, vì vậy nếu nó hoạt động mà không có một Tôi sẽ rất ấn tượng.

+3

Nguyên tắc về phong cách của Apple khuyên bạn không nên sử dụng "và" cho các phần tiếp theo của tên phương thức của bạn. (Từ tài liệu bạn vừa liên kết: "Không sử dụng" và "để liên kết các từ khoá là thuộc tính của người nhận.") Vì vậy, bộ chọn đó chỉ nên là 'sendEmailToPerson: withSubject: body: attachment:'. – Chuck

+2

@Chuck: Thấy không? Nói với bạn tôi không phải là một chuyên gia. Chỉnh sửa. –

+2

Câu trả lời hay. Một lưu ý bổ sung mà bạn đưa vào mã của mình nhưng không đề cập đến: Phần đầu tiên của bộ chọn không được viết hoa. Vì vậy, bạn sẽ [john greetPerson] thay vì [john GreetPerson:]. Tôi biết nitpicking của nó, nhưng Objective-C programers rất cụ thể về cú pháp và hướng dẫn phong cách! Vốn chào là rất Java. – micmoo

2

Phần "đầu tiên" của phương pháp là selector, ví dụ của bạn bao gồm -greet:toPerson:greetWith:, đây là tên thực tế của phương pháp.

Phần "thứ hai" thứ hai là các tham số của phương thức, trong ví dụ của bạn là, chúc mừng.

Đây là giống như một cái gì đó như C, nơi bạn sẽ có

int greet(string to, string greeting) { 
    print(greeting, to); 
} 

Tôi cũng nên đề cập đến, bạn có thể sẽ muốn làm việc với NSString * thay vì char *NSLog() thay vì printf() (không lo lắng, nó hoạt động gần như giống hệt nhau).

0

Có lẽ nó muốn được:

[personJohn greetPerson:@"Kelly" withGreeting:@"hey babe"]; 

Đối tượng người đã là John và anh ấy chào hỏi một đối tượng người, mà tôi sẽ không định nghĩa như là một chuỗi như bạn đã làm, nhưng thay vào đó là một ví dụ của lớp Người, và sau đó bạn có thể làm greetWithString.

[personJohn greetPerson:personKelly withGreeting:@"hey babe"]; 

Bạn không xác định tham số hai lần, đó là nơi bạn đang bối rối. Nếu bạn biết C++, bạn thường có:

void greetPerson(Person thePerson, string greeting); 

làm nguyên mẫu hàm chẳng hạn. Sau đó, bạn sẽ gọi nó là như vậy:

greetPerson(personKelly, "hey babe"); 

Bây giờ, tất cả mục tiêu-c đang làm là giúp bạn dễ dàng bằng cách tự ghi chép tài liệu. Thay vì chỉ đặt các thông số vào các hàm, bạn đặt tên cho chúng trước khi bạn nêu, vì vậy cuộc gọi ở trên sẽ là:

greetPerson(Person:personKelly, greeting:"hey babe"); 

cho mẫu thử chức năng được đăng ở trên. Bằng cách này khi bạn đọc mã, bạn biết những gì mỗi tham số đang làm, do đó là tự tài liệu. Nó có vẻ tẻ nhạt lúc đầu, nhưng khả năng đọc mã được tăng lên rất nhiều.

0

Tên của phương pháp bạn mô tả ở trên là "Greet: toPerson: greetWith:". Các dấu hai chấm là một phần của tên. Các tham số (và các kiểu số của chúng) không.

Phong cách lưu ý: không bắt đầu một tên phương pháp với một chữ hoa, trừ khi bạn đang đề cập đến một từ viết tắt (như "URL".)

4

Những người khác đã đề cập những điểm quan trọng nhất, vì vậy tôi sẽ chỉ cần cân nhắc một số câu hỏi bổ sung:

Điều gì đó làm phiền tôi và đó là tên của tham số đầu tiên về cơ bản giống như tên của 'thông điệp'. Làm thế nào để bạn giải quyết bằng văn bản phương thức có ý nghĩa và dễ hiểu/'tên thông điệp'?

Cách phổ biến nhất để giải quyết vấn đề này là đặt tên phương thức là sự kết hợp của "cái gì là/không" và nhãn cho tham số đầu tiên. Ví dụ:

NSColor * color = [NSColor colorWithDeviceRed:0.5 green:0.5 blue:0.5 alpha:0.5]; 

Ai đó có thể giải thích lý do cho hai tên cho từng tham số và có thể là một ví dụ hữu ích hơn về cách thức này có thể được sử dụng một cách hiệu quả để đưa ý nghĩa trong chương trình?

Câu trả lời nhanh là hai tên được dành cho các đối tượng khác nhau; một là dành cho người sử dụng phương pháp này, cái kia dành cho tác giả của phương thức. Hãy xem xét ví dụ trên một lần nữa. Tuyên bố phương pháp giống như sau:

+ (NSColor *)colorWithDeviceRed:(CGFloat)red 
          green:(CGFloat)green 
          blue:(CGFloat)blue 
          alpha:(CGFloat)alpha 

Khi người dùng gọi phương thức đó, họ quan tâm đến nhãn đầu tiên (những người trước dấu hai chấm). Bạn có thể thấy trong ví dụ đầu tiên của tôi, nơi các giá trị kênh được truyền dưới dạng hằng số, chỉ có các nhãn được nhìn thấy trong mã.

Tên thông số thực tế (các phần sau loại), được sử dụng trong định nghĩa phương pháp và thực sự chỉ có cho người lập trình viết phương pháp, vì đó là các biến sẽ có sẵn trong chính thân phương thức.

+0

Xem thêm: http://stackoverflow.com/questions/683211/method-syntax-in-objective-c –

Các vấn đề liên quan