You can declare a method in objective-c and name each parameter twice, basically.
I get the idea that this is powerful, but I'm not quite sure how to use it yet...
When John Greets Kelly:
[ p Greet:"John" toPerson:"Kelly" greetWith:"hey babe" ] ;
Something about it doesn't read naturally. I'm not sure if that's how an experienced objective-c programmer would write that "message".
Can someone explain the reason for two names for each parameter and possibly a more useful example of how this can be used effectively to put meaning in the program?
Also something bothers me and that is the name of the first parameter is basically the same as the name of the 'message'. How do you resolve that in writing meaningful and understandable method/'message names'?
#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; }
When Objective-C migration is perfect and developers beg managers for permission, Apple will say, "You should really be using Swift", and discourage Objective-C. Years later, it may be deprecated, but it never will be removed. It powers iOS, and years after deprecation OS X still runs bits of Carbon.
Objective-C is a programming language. A programming language is an abstract concept. A programming language is a set of mathematical rules and definitions. Programming languages aren't compiled or interpreted, they just are.
And again, the colons are just separators to indicate that a parameter is coming. So there you go – now you can read an Objective-C method declaration that takes multiple parameters and returns a value, wacky syntax and all.
Objective-C uses all of the same logical operators as C. || is the logical-or operator.
First things first: as a stylistic note, bring your braces together:
[ Person alloc ]
should be
[Person alloc]
I also note that you're forgetting to initialize Person when you alloc it, you should be using:
Person *p = [[Person alloc] init];
Getting the feel for how to declare methods takes a little bit of time. Examining how the framework names its methods is useful. For your specific example, I think you're overengineering. You're looking for something like this:
Person *john = [[Person alloc] initWithName:@"John"];
Person *kelly = [[Person alloc] initWithName:@"Kelly"];
[john greetPerson:kelly withGreeting:@"Hey babe."];
[kelly greetPerson:john withGreeting:@"Get bent."];
Notice that I've not capitalized the g
in greetPerson
, either. That's a stylistic convention of Objective-C.
Don't forget that an object has its own identity, so rarely do you need to instruct an object (meant to represent a person) who it is before it talks to someone. When you write a message, it should read like English. When you get into multiple arguments -- admittedly, rare -- start thinking with commas:
[john sendEmailToPerson:kelly withSubject:subject body:body attachments:nil];
See how that flows? And even that leaves some to be desired, I don't have this mastered yet either. Give it time.
A very useful document on this is Apple's Coding Guidelines for Cocoa.
Also, get yourself out of the C trap. Here's how I'd write your entire program (I'm introducing a boatload of concepts, so don't expect to understand all of it):
#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;
}
This code is completely untested, so if it works without a hitch I'll be duly impressed.
Other people have covered the most important points, so I'll just weigh in on some of the supplementary questions:
Also something bothers me and that is the name of the first parameter is basically the same as the name of the 'message'. How do you resolve that in writing meaningful and understandable method/'message names'?
The most common way of dealing with this is to make the method name a combination of "what it is/does" and the label for the first parameter. Example:
NSColor * color = [NSColor colorWithDeviceRed:0.5 green:0.5 blue:0.5 alpha:0.5];
Can someone explain the reason for two names for each parameter and possibly a more useful example of how this can be used effectively to put meaning in the program?
The quick answer is that the two names are intended for different audiences; one is for the user of the method, the other is for the author of the method. Consider the above example again. The method declaration looks like this:
+ (NSColor *)colorWithDeviceRed:(CGFloat)red
green:(CGFloat)green
blue:(CGFloat)blue
alpha:(CGFloat)alpha
When a user calls that method, they are concerned with the first labels (the ones before the colon). You can see in my first example, where the channel values are passed as numeric constants, that only the labels are seen in code.
The actual parameter names (the parts after the type), are used within the method definition, and as such are really only there for the programmer who writes the method, since those are the variables that will be available within the method body itself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With