Okay. Tough to find the best starting point, here. The error XCode (4.3.2) in Lion is kicking back to me is:
Redefinition of 'a' with a different type
The author says when we declare this line (near the bottom of this page, in main)…
OwnedAppliance *a = [[OwnedAppliance alloc] init];
…that it should run fine. It doesn’t. It kicks back the error above. I understand that, because OwnedAppliance has no init method in its implementation, the compiler will go up the hierarchy to OwnedAppliance’s superclass, which is Appliance, and search for an init method there. It finds the overridden init, which contains only the following line…
[self initWithProductName:@"Unknown"];
…and runs that. Understood.
Ugh. Sorry, guys. I just tried to explain what I think might be happening. It took a dozen lines and I’d just scratched the surface. Rather than bore you with what I think is happening, I’ll just ask:
What’s going on with this code? Where does the initialization “path”, for lack of a better term, end? Where does the redefinition (the error) occur?
/******************** Appliance.h ********************/
#import <Foundation/Foundation.h>
@interface Appliance : NSObject
{
NSString *productName;
int voltage;
}
@property (copy) NSString *productName;
@property int voltage;
-(id)init;
// Designated initializer
-(id)initWithProductName:(NSString *)pn;
...
@end
/******************** Appliance.m ********************/
#import "Appliance.h"
@implementation Appliance
@synthesize productName, voltage;
-(id)init
{
return [self initWithProductName:@"Unknown"];
}
-(id)initWithProductName:(NSString *)pn
{
self = [super init];
if (self) {
[self setProductName: pn];
[self setVoltage: 120];
}
return self;
...
@end
/******************** OwnedAppliance.h ********************/
#import "Appliance.h"
@interface OwnedAppliance : Appliance
{
NSMutableSet *ownerNames;
}
// Designated initializer
-(id)initWithProductName:(NSString *)pn
firstOwnerName:(NSString *)n;
...
@end
/******************** OwnedAppliance.m ********************/
#import "OwnedAppliance.h"
@implementation OwnedAppliance
-(id)initWithProductName:(NSString *)pn
firstOwnerName:(NSString *)n
{
self = [super initWithProductName:pn];
if (self) {
ownerNames = [[NSMutableSet alloc] init];
if (n) {
[ownerNames addObject:n];
}
}
return self;
}
-(id)initWithProductName:(NSString *)pn
{
return [self initWithProductName:pn
firstOwnerName:nil];
}
...
@end
/******************** main.m ********************/
#import <Foundation/Foundation.h>
#import "Appliance.h"
#import "OwnedAppliance.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
// Previously omitted problematic code:
Appliance *a = [[Appliance alloc] init];
NSLog(@"a is %@", a);
[a setProductName:@"Washing Machine"];
[a setVoltage:240];
NSLog(@"a is %@", a);
// The following line is where the error occurs:
OwnedAppliance *a = [[OwnedAppliance alloc] init];
...
}
return 0;
}
I’ve thought a lot about this question and how to ask it. I don’t think it’s a terribly dumb one. 🙂 But my brain is fried from 9 hours of studying this stuff, so I apologize if this is a totally obvious question. TIA
EDIT: main() now contains the code that was actually causing the error. Thanks to Jacques for being good enough to catch it despite the omission.
The compiler’s actually telling you that the variable itself,
a, has been declared twice; the error has nothing to do with the assignment. Somehwhere else, in scope, you have another variable nameda, which has a different type thanOwnedAppliance *. Change the name(s) of one (or both) and the error will go away.