You are confusing the runtime and the compiler. The runtime has no problem coping with that. The issue is that dot notation (which is syntactic sugar) requires type information for the compiler to disambiguate between Objective-C objects and C structs.
If you don't use dot notation it works:
NSLog( @"%@ : %@\n", [exc name], [exc reason]) ;
The above will generate a warning if the type is not id since the compiler knows it does know the type and can't guarantee the dispatch will work, but it will compile and run.
Fundamentally the issue at hand is the compiler needs to know whether to generate a structure load, or an Objective C dispatch, in other words, with dot notation it needs to have enough information to determine the difference between an object and a scalar type.
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.
Best Answer
Have a look here at the end of the post the blogger says to write:
It seems like you always have to pass through GNUStep