Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

johnmerlino

macrumors member
Original poster
Oct 22, 2011
81
0
Hey all,

I get following error:

objective-c compile error: Initializing NSString with an expression of incompatible type void.

Basically my speak instance method should return a string and then I want to output that string as part of a message:

Code:
    Animal *animal = [[Animal alloc] init];
    NSString *speak = [animal speak];
    NSLog(@"The animal says %@", speak);

Code:
@implementation Animal

- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code here.
    }
    
    return self;
}

- (void)dealloc
{
    [super dealloc];
}

- (void)speak{
    NSLog(@"Hi there");
}

@end

Here's basically my problem. Since objective-c uses the NNString class as its string implementation, I am not sure how to return it as the value of speak.

thanks for response
 
I get following error:

objective-c compile error: Initializing NSString with an expression of incompatible type void.

Basically my speak instance method should return a string and then I want to output that string as part of a message:

Well, you declared a "speak" method returning void, and the implementation of that void method returns nothing. You'd need to declare it as returning an NSString*, and change the implementation to return an NSString*, for example @"Hi there"
 
Well, you declared a "speak" method returning void, and the implementation of that void method returns nothing. You'd need to declare it as returning an NSString*, and change the implementation to return an NSString*, for example @"Hi there"

I already tried that. It says NSString cannot be returned by value.
 
I already tried that. It says NSString cannot be returned by value.

It is essential for any programming effort to read and write very precisely. I never said you should write a method that returns an NSString. I said you should write a method that returns an NSString*.

You never, ever, ever have any variables, parameters, return values, or expressions of type NSObject or any subclass of NSObject, like NSString. You _always_ use pointers, like NSObject* or NSString*.
 
Got it working:

Code:
    Animal *animal = [[Animal alloc] init];
    [animal setName:(NSString*) @"Dog"];
    NSLog(@"The name of the animal is %@", [animal name]);

@interface Animal : NSObject {
@private
    NSString *name;
    NSString *diet;
    NSString *habitat;
    NSDate *originDate;
}

- (NSString*) name;
- (void) setName:(NSString*) name;

@end


@implementation Animal
- (void)setName:(NSString*) animalName{
    name = animalName;
}

- (NSString*)name{ 
    return name;
}
 
Got it working:

Code:
    Animal *animal = [[Animal alloc] init];
    [animal setName:(NSString*) @"Dog"];
    NSLog(@"The name of the animal is %@", [animal name]);

Careful with casts. Most casts are either unnecessary, or wrong. In (NSString*) @"Dog", the cast is unnecessary, because @"Dog" is a special syntax for an NSString* with the contents "Dog".
 
Careful with casts. Most casts are either unnecessary, or wrong. In (NSString*) @"Dog", the cast is unnecessary, because @"Dog" is a special syntax for an NSString* with the contents "Dog".


thanks for response, to make it easier I tried using the accessor method creation:
Code:
@interface Animal : NSObject { 
@private
    NSString *diet;
}
@property NSString* diet;


@implementation Animal
@synthesize diet;

But this line gives a warning:
Code:
@property NSString* diet;

"default property attribute assign not appropriate for non-gc object"

That said, it does compile. Im just wondering why it's giving me that warning.
 
"default property attribute assign not appropriate for non-gc object"

That said, it does compile. Im just wondering why it's giving me that warning.

Whenever you get a warning, you better find out why. A "warning" is the compiler telling you that you are doing something that is legal according to the rules of the language, but likely to get you into trouble.

You'll have to read up on memory management first. Your setName method didn't take ownership of the object, which means if the caller releases the object, you will get a crash. Since that is done in code you explicitely wrote, the compiler gives you what you want. With the @property syntax, the default is exactly the same, "assign". But since you didn't write anything, the compiler tells you that this is most likely wrong, and "retain" is probably what you want.
 
Whenever you get a warning, you better find out why. A "warning" is the compiler telling you that you are doing something that is legal according to the rules of the language, but likely to get you into trouble.

You'll have to read up on memory management first. Your setName method didn't take ownership of the object, which means if the caller releases the object, you will get a crash. Since that is done in code you explicitely wrote, the compiler gives you what you want. With the @property syntax, the default is exactly the same, "assign". But since you didn't write anything, the compiler tells you that this is most likely wrong, and "retain" is probably what you want.

What you are saying is that using @property to declare setter/getter methods will default the method body to an assign. In essence, the setter method will just do a simple assignment of the instance variable to the new value. The problem is then that since Objective-C objects use reference counting, and therefore by not retaining the object, there is a chance that the string could be deallocated while it is still in use. Then the solution would be to retain the new value in the setter method:

Code:
@synthesize diet;
- (void)setDiet:(NSString*) d{
    [d retain];
    [d release];
    diet = d;
}

Then this raises a new warning:
"writable atomic property 'diet' cannot pair a synthesized setter/getter with a user defined setter/getter. But then again if I don't explicitly state that I want to maintain a reference of the object, and that I must release it before it will be deallocated, I will get that warning ""default property attribute assign not appropriate for non-gc object".

So I see a catch-22 here. @synthesize cannot be used with objects, it appears.
 
So I see a catch-22 here. @synthesize cannot be used with objects, it appears.

You need to look more carefully at the syntax for declaring properties. There are attribute names you should use, such as copy, retain, nonatomic. These attributes go on the @property declaration, not the @synthesize. Read the Declared Properties section of the language reference guide.


What book or tutorial are you learning Objective-C from? Please be specific. Whatever it is, you should probably read through the Objective-C Primer, too.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.