Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[beginner] Problem with @property under GNU/Linux

28 views
Skip to first unread message

Hamiral

unread,
Nov 3, 2009, 11:15:35 AM11/3/09
to
Hello,

I'm learning Objective-C with gobjc under Ubuntu GNU/Linux and I'm
trying to compile some source with properties, but the compiler gives me
error messages I don't understand. It seems like it doesn't know the
@property directive. Maybe I'm missing some compiler options ?
Here is my source code :

** Vector3D.h
#import <objc/Object.h>

@interface Vector3D : Object {
float x;
float y;
float z;
}
@property(readwrite) float x;
@property(readwrite) float y;
@property(readwrite) float z;

-(id) init;
-(id) initWithX: (float) aX Y: (float) aY Z: (float) aZ;
-(void) release;
@end

** Vector3D.m
#import "Vector3D.h"

@implementation Vector3D

@synthesize x;
@synthesize y;
@synthesize z;

-(id) init
{
self = [super init];
if(self) {
x = 0.0;
y = 0.0;
z = 0.0;
}

return self;
}

-(id) initWithX: (float) aX Y: (float) aY Z: (float) aZ
{
self = [super init];
if(self) {
x = aX;
y = aY;
z = aZ;
}

return self;
}

-(void) release
{
}
@end

When I'm compiling with this command :
gcc -c -Wno-import -Wall Vector3D.m

I get these error messages :
In file included from Vector3D.m:1:
Vector3D.h:8: error: stray ‘@’ in program
Vector3D.h:8: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’
before ‘float’
Vector3D.h:9: error: stray ‘@’ in program
Vector3D.h:9: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’
before ‘float’
Vector3D.h:10: error: stray ‘@’ in program
Vector3D.h:10: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’
before ‘float’
Vector3D.m:5: error: stray ‘@’ in program
Vector3D.m:5: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’
before ‘x’
Vector3D.m:6: error: stray ‘@’ in program
Vector3D.m:6: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’
before ‘y’
Vector3D.m:7: error: stray ‘@’ in program
Vector3D.m:7: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’
before ‘z’

Can someone tell me what I'm doing wrong ?

Thanks a lot in advance.

Ham

Tom Harrington

unread,
Nov 3, 2009, 11:34:45 AM11/3/09
to
In article <4af05727$0$2460$426a...@news.free.fr>,
Hamiral <ham...@hamham.com> wrote:

> I'm learning Objective-C with gobjc under Ubuntu GNU/Linux and I'm
> trying to compile some source with properties, but the compiler gives me
> error messages I don't understand. It seems like it doesn't know the
> @property directive. Maybe I'm missing some compiler options ?

Does gobjc implement Objective-C 2.0? Some quick Googling has not
turned up an answer for me. That's where @property was introduced, and
it was an Apple addition. I don't know if non-Apple compilers recognize
it yet.

--
Tom "Tom" Harrington
Independent Mac OS X developer since 2002
http://www.atomicbird.com/

Hamiral

unread,
Nov 3, 2009, 12:01:10 PM11/3/09
to
Tom Harrington wrote:
> In article <4af05727$0$2460$426a...@news.free.fr>,
> Hamiral <ham...@hamham.com> wrote:
>
>> I'm learning Objective-C with gobjc under Ubuntu GNU/Linux and I'm
>> trying to compile some source with properties, but the compiler gives me
>> error messages I don't understand. It seems like it doesn't know the
>> @property directive. Maybe I'm missing some compiler options ?
>
> Does gobjc implement Objective-C 2.0? Some quick Googling has not
> turned up an answer for me. That's where @property was introduced, and
> it was an Apple addition. I don't know if non-Apple compilers recognize
> it yet.
>

I've just searched on the web. As you guessed, it looks like gobjc
doesn't support Objective-C 2.0 features because they're proprietary
additions by Apple :(
So I will have to learn the "old" Objective-C only...

Thank you anyway

Ham

Tom Harrington

unread,
Nov 3, 2009, 1:51:52 PM11/3/09
to
In article <4af061d6$0$25378$426a...@news.free.fr>,
Hamiral <ham...@hamham.com> wrote:

Well, Apple added them, but as for being proprietary, they do follow the
GPL. Their changes can be found at <http://opensource.apple.com/>.

Hamiral

unread,
Nov 3, 2009, 1:55:24 PM11/3/09
to
Tom Harrington wrote:
>> I've just searched on the web. As you guessed, it looks like gobjc
>> doesn't support Objective-C 2.0 features because they're proprietary
>> additions by Apple :(
>> So I will have to learn the "old" Objective-C only...
>
> Well, Apple added them, but as for being proprietary, they do follow the
> GPL. Their changes can be found at <http://opensource.apple.com/>.

Oh ok, sorry. I misunderstood something I read on a forum.
Well then that means I'll have to wait before using those additional
features.

Ham

Sherm Pendley

unread,
Nov 3, 2009, 2:14:54 PM11/3/09
to
Hamiral <ham...@hamham.com> writes:

> Well then that means I'll have to wait before using those additional
> features.

Yes, but it's not *that* big a loss. All that @property really does is
automagically generate some boilerplate code for accessor methods,
and writing that code by hand is a learning experience anyway. :-)

sherm--

Hamiral

unread,
Nov 3, 2009, 2:25:16 PM11/3/09
to

Herm yes, it looks to me that accessors are not trivial for a beginner.
Especially the use of retain/copy and release...

For example I have a Camera class which has a position member which is a
Vector3D.

I'm writing accessors for this position, but I don't know if I should
write it like this :
-(void) setPosition: (Vector3D *)pos
{
position = [pos copy];
}

or like this :
-(void) setPosition: (Vector3D *)pos
{
[position release];
position = [pos retain];
}

Generally speaking, when should I use the first form or the second one ?

Thanks again (yes I ask lots of questions ;))

Ham

Sherm Pendley

unread,
Nov 3, 2009, 2:54:09 PM11/3/09
to
Hamiral <ham...@hamham.com> writes:

> Sherm Pendley wrote:
>> Hamiral <ham...@hamham.com> writes:
>>
>>> Well then that means I'll have to wait before using those additional
>>> features.
>>
>> Yes, but it's not *that* big a loss. All that @property really does is
>> automagically generate some boilerplate code for accessor methods,
>> and writing that code by hand is a learning experience anyway. :-)
>
> Herm yes, it looks to me that accessors are not trivial for a
> beginner. Especially the use of retain/copy and release...

Precisely my point! @property removes the need to write accessors by
hand, but it's not a substitute for understanding them.

> For example I have a Camera class which has a position member which is
> a Vector3D.
>
> I'm writing accessors for this position, but I don't know if I should
> write it like this :
> -(void) setPosition: (Vector3D *)pos
> {
> position = [pos copy];
> }
>
> or like this :
> -(void) setPosition: (Vector3D *)pos
> {
> [position release];
> position = [pos retain];
> }
>
> Generally speaking, when should I use the first form or the second one ?

The question is, what happens if some other code modifies the pos object
in some way, while your Camera object still has a reference to it? If the
answer is "bad things will happen," then your Camera object will want
to make its own private copy of pos, to ensure against that possibility.

On the other hand, either accessor should take into account the possibility
that pos and position may be the same object, and accessors that use
copy should still release the old value of position. For example:

-(void) setPosition: (Vector3D*) pos {
if (pos != position) {
[position release];
position = [pos retain]; // Or [pos copy], as needed
}
}

One important thing to note is that accessors should be the only place
you ever send -copy, -retain, or -release messages. Scattering them
here and there throughout your app will make it *very* difficult to
ensure that every -copy or -retain is balanced with a corresponding
-release.

sherm--

Hamiral

unread,
Nov 3, 2009, 3:08:14 PM11/3/09
to

Ok, but something I'm still not sure about :
if I implement my setPosition with [pos copy], what happens if I call it
this way :

[camera setPosition: [[Vector3D alloc] initWithX: x andY: y andZ: z]];

Will my program have a memory leak on that line of code ?

or maybe I should rewrite my setPosition like this, to avoid any problem :

-(void) setPositionX: (float) x andY: (float) y andZ: (float) z
{
// position has been alloc'ed and init'ed in init
[position setX: x andY: y andZ: z];
}

What would you suggest ?

Thanks again

Ham

Sherm Pendley

unread,
Nov 3, 2009, 3:32:37 PM11/3/09
to
Hamiral <ham...@hamham.com> writes:

> Ok, but something I'm still not sure about :
> if I implement my setPosition with [pos copy], what happens if I call
> it this way :
>
> [camera setPosition: [[Vector3D alloc] initWithX: x andY: y andZ: z]];
>
> Will my program have a memory leak on that line of code ?

Yes - so don't do that. :-)

I'd write it like this:

[camera setPosition: [Vector3D vector3DWithX:x andY:y andZ:z]];

Your +vectorWithX:andY:andZ: method would then look something like this:

+(Vector3D*) vector3DWithX:(float)x andY:(float)y andZ:(float)z {
return [[[self alloc] initWithX:x andY:y andZ:z] autorelease];
}

The idea here is consistency. The alternative is having to remember
which accessors retain or copy their argument, and which ones expect
that to have already been done. That breaks encapsulation, because it
makes you think about the internal implementation details of the Camera
class when you're writing client code that uses it.

sherm--

Hamiral

unread,
Nov 4, 2009, 7:48:08 AM11/4/09
to
Sherm Pendley wrote:
>> [camera setPosition: [[Vector3D alloc] initWithX: x andY: y andZ: z]];
>>
>> Will my program have a memory leak on that line of code ?
>
> Yes - so don't do that. :-)

Ok :)

> I'd write it like this:
>
> [camera setPosition: [Vector3D vector3DWithX:x andY:y andZ:z]];
>
> Your +vectorWithX:andY:andZ: method would then look something like this:
>
> +(Vector3D*) vector3DWithX:(float)x andY:(float)y andZ:(float)z {
> return [[[self alloc] initWithX:x andY:y andZ:z] autorelease];
> }
>
> The idea here is consistency. The alternative is having to remember
> which accessors retain or copy their argument, and which ones expect
> that to have already been done. That breaks encapsulation, because it
> makes you think about the internal implementation details of the Camera
> class when you're writing client code that uses it.

Thanks a lot.
But I don't think I can use autorelease, because it seems there is no
NSAutoreleasePool in the gobjc implementation :(

But, as I may move quite frequently my camera, I don't think allocating
a new Vector3D object each time I want to change the camera position
would be very efficient, so in this particular case I should just update
it like this :
-(void) setPositionX:(float)x andY:(float) y andZ:(float)z;
and update internally the position.

But, in a general case, how could use your method without an autorelease
pool ?

Thanks again (I'm sorry I'm a real beginner, I have a lot of questions)

Ham

Hamiral

unread,
Nov 4, 2009, 7:56:29 AM11/4/09
to
Hamiral wrote:
> But, in a general case, how could use your method without an autorelease
> pool ?

Oh I think I got it, please tell me if it's ok to do it this way :

+(Foo*) fooWithParam:(float)param
{
return [[[self alloc] initWithParam:param];
}

and in the other class :

-(void) setFoo:(Foo*)foo
{
self->foo = [foo copy];
[foo release];
}

and then :
[myobject setFoo:[Foo fooWithParam:p]];

For me it doesn't look right : what would happen if the user writes this :
Foo * foo = [[Foo alloc] initWithParam:p];
[myobject setFoo:foo];
[foo someOtherMessage];

It looks like without an autorelease pool, I'm stuck :(

Ham

Sherm Pendley

unread,
Nov 4, 2009, 9:15:17 AM11/4/09
to
Hamiral <ham...@hamham.com> writes:

> But I don't think I can use autorelease, because it seems there is no
> NSAutoreleasePool in the gobjc implementation :(

It's part of the Foundation framework, which is implemented in GNUStep.
You're using many other parts of Foundation successfully, such as +alloc
and -release.

> But, in a general case, how could use your method without an
> autorelease pool ?

I wouldn't.

sherm--

Sherm Pendley

unread,
Nov 4, 2009, 9:17:56 AM11/4/09
to
Hamiral <ham...@hamham.com> writes:

> Hamiral wrote:
>> But, in a general case, how could use your method without an
>> autorelease pool ?
>
> Oh I think I got it, please tell me if it's ok to do it this way :
>
> +(Foo*) fooWithParam:(float)param
> {
> return [[[self alloc] initWithParam:param];
> }

No, it is not OK to do it that way. The proper design pattern here is
that methods beginning with +alloc, or containing -copy, will return
objects that the caller owns and must release. Other methods, such as
the one above, return objects that the caller does *not* own.

sherm--

Hamiral

unread,
Nov 4, 2009, 9:55:05 AM11/4/09
to
Sherm Pendley wrote:
> Hamiral <ham...@hamham.com> writes:
>
>> But I don't think I can use autorelease, because it seems there is no
>> NSAutoreleasePool in the gobjc implementation :(
>
> It's part of the Foundation framework, which is implemented in GNUStep.
> You're using many other parts of Foundation successfully, such as +alloc
> and -release.

Ah yes you're right !
I first installed only gobjc, which doesn't provide any framework, only
the basic language features.
Now I just installed libgnustep-base, and while linking with it, I can
use the NSAutoreleasePool. Great :)

Thanks !

Ham

0 new messages