Type of property...does not match type of instance variable


#1

Hi team,

Relatively easy question, I hope. I’m sure I am missing something quite obvious here.

I am getting four errors in my implementation when I try to @sythesize. They all have the same format and read as follows:

Type of property ‘itemName’ (‘BNRItem *’) does not match type of instance variable ‘itemName’ (‘NSString *__strong’)

The errors appear for itemName, serialNumber, valueInDollars, and dateCreated.

My .h file reads as follows:

[code]#import <Foundation/Foundation.h>

@interface BNRItem : NSObject
{
NSString *itemName;
NSString *serialNumber;
int valueInDollars;
NSDate *dateCreated;

BNRItem *containedItem;
__weak BNRItem *container;

}

  • (id)randomItem;
  • (id)initWithItemName:(NSString *)name
    valueInDollars:(int)value
    serialNumber:(NSString *)sNumber;

@property (nonatomic, strong) BNRItem *containedItem;
@property (nonatomic, weak) BNRItem *container;

@property (nonatomic, strong) BNRItem *itemName;
@property (nonatomic, strong) BNRItem *serialNumber;
@property (nonatomic) int *valueInDollars;
@property (nonatomic, readonly, strong) BNRItem *dateCreated;

@end[/code]

And my .m file reads as follows:

[code]#import “BNRItem.h”

@implementation BNRItem
@synthesize itemName;
@synthesize containedItem, container, serialNumber, valueInDollars, dateCreated;

  • (id)randomItem
    {
    //Create an an array of three adjectives
    NSArray *randomAdjectiveList = [NSArray arrayWithObjects:
    @“Fluffy”,
    @“Rusty”,
    @“Shiny”, nil];

    //Create an array of three nouns
    NSArray *randomNounList = [NSArray arrayWithObjects:
    @“Bear”,
    @“Spork”,
    @“Mac”, nil];

    //Get the index of a random adjective/noun from the lists
    //Note: The % operator, called the modulo operator, gives you the remainder. So adjectiveIndex is a random number from 0 to 2 inclusive.
    NSInteger adjectiveIndex = rand() % [randomAdjectiveList count];
    NSInteger nounIndex = rand() % [randomNounList count];

    //Note that NSIteger is not an object, but a type definiteion for “unsigned long”

    NSString *randomName = [NSString stringWithFormat:@"%@ %@", [randomAdjectiveList objectAtIndex:adjectiveIndex], [randomNounList objectAtIndex:nounIndex]];

    int randomValue = rand() % 100;

    NSString *randomSerialNumber = [NSString stringWithFormat:@"%c%c%c%c%c",
    ‘0’ + rand() % 10,
    ‘A’ + rand() % 26,
    ‘0’ + rand() % 10,
    ‘A’ + rand() % 26,
    ‘0’ + rand() % 10];
    BNRItem *newItem = [[self alloc] initWithItemName:randomName
    valueInDollars:randomValue
    serialNumber:randomSerialNumber];

    return newItem;
    }

  • (void) dealloc
    {
    NSLog(@“Destroyed: %@”, self);
    }

  • (id)init
    {
    return [self initWithItemName:@“Item” valueInDollars:0 serialNumber:@""];
    }

  • (id)initWithItemName:(NSString *)name valueInDollars:(int)value serialNumber:(NSString *)sNumber
    {
    //Call the superclass’ designated initializer
    self = [super init];

    //Did the superclass’ designated inializer succeed?
    if (self)
    {
    //Give the instance variables initial values
    [self setItemName:name];
    [self setSerialNumber:sNumber];
    [self setValueInDollars:value];
    dateCreated = [[NSDate alloc] init];
    }
    //Return the address of the newly initialized object
    return self;
    }

  • (void)setContainedItem: (BNRItem *)i
    {
    containedItem = i;

    //When given an item to contain, the contained item will be given a pointer to it’s container
    [i setContainer:self];
    }

  • (NSString *)description
    {
    NSString *descriptionString =
    [[NSString alloc] initWithFormat:@"%@ (%@) Worth: $%d, recorded on %@",
    itemName,
    serialNumber,
    valueInDollars,
    dateCreated];

    return descriptionString;
    }

@end[/code]

Any thoughts?

And big thanks,
Ben


#2

Your @property declarations for itemName and serialNumber should not be of type BNRItem *. They are part of the BNRItem class, but are not themselves BNRItem objects.

This -

@property (nonatomic, strong) NSString *itemName;
@property (nonatomic, strong) NSString *serialNumber;

instead of this in your code -

@property (nonatomic, strong) BNRItem *itemName;
@property (nonatomic, strong) BNRItem *serialNumber;

Hope that helps.


#3

Instead of strong attribute make it copy attribute. Although it is not very important but a good practice… Making your NSString type property have a copy attribute, not only makes strong reference but also ensures safety against string mutation…
Here’s an easy example:
main.m

#import <Foundation/Foundation.h>
#import "TestClass.h"
int main(int argc, const char * argv[])
{

    @autoreleasepool {
        NSMutableString *str=[NSMutableString stringWithFormat:@"rahul"];
        TestClass *test=[TestClass new];
        [test setName:str];
        NSLog(@"%@",[test name]);
    }
    return 0;
}

TestClass.h

#import <Foundation/Foundation.h>

@interface TestClass : NSObject
{
    NSMutableString *name;
}
-(void)setName:(NSMutableString *)name;
-(NSMutableString *)name;
@end

TestClass.m

#import "TestClass.h"
@implementation TestClass
-(void)setName:(NSMutableString *)currentName{
   
    name=[currentName copy];
    [currentName setString:@"luhar"];//This would also change the change the ivar- name to "luhar".To avoid this, a separate copy of original string is given to ivar-name by local pointer-currentName.
   
}
-(NSMutableString *)name{
    return name;
}
@end