discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Setter Gettor method style


From: Alexander Malmberg
Subject: Re: Setter Gettor method style
Date: Sun, 04 Aug 2002 22:41:27 +0200

[snip]
> I find it difficult to choose one way or another.

I agree. 'return foo;' is faster and easier to write. Thread safety is
probably the main issue.

>From the linked discussion, it seems that mosx is moving towards 'return
[[foo retain] release];', so computability might resolve this issue for
us :).

> The point is that we're speaking of attributes:
> 
[snip]
> 
> I feel that the right solution is to take copies and return copies:
> 
>   -(void)setAttribute:(NSString*)newValue
>   {
>      [_attribute release];
>      _attribute=[[newValue copy/*or mutableCopy if it can be edite by self*/]
>                       retain];
>   }//setAttribute:;

I agree. Setters (of this kind) should make a copy and not use a mutable
passed-in object.

>   -(NSString*)getAttribute
>   {
>     return([_attribute copy]);
>   }//getAttribute;

In this case, since it's an immutable object, a copy is equivalent to a
retain, but even when it isn't, I don't see why we would want to make a
copy here. The caller has no business mucking around with the value an
accessor returns.

[snip]
> Well, since getAttribute returns a copy for the exclusive usage of the
> caller, it could as well return a mutableCopy to allow the called edit
> the result without having to do a new mutable copy itself.

This would be one approach, but for some reason the convention is to
return an immutable object, and I don't think we can change that now.

> What is the difference in performance of copy and mutableCopy?

Depends. -copy on an immutable object (like an NSString) is equivalent
to a retain and is quite fast. A 'real' copy, like -mutableCopy always
does, and -copy does sometimes, can potentially be much slower (eg. huge
NSData objects).

[snip]
>   -(void)setAttribute:(NSString*)newObject
>   {
>      [_attribute release];
>      _attribute=[newObject retain];
>   }//setAttribute:;

IMO -copy should be used here. If newObject is already immutable it's as
fast as -retain, and if it isn't we get a copy, like we should.

[snip]
> Now, about the gettor.

I think I'll try to clarify how I think about this. In one case, you
have a 'relationship' with an object, like NSArray, or NSWindow's
contentView (and I consider this more of 'containment' than attribute).
In the other, you have a 'relationship' with a value, like NSWindow's
title. The object that carries the value is of no interest of itself.

> If  you consider you  have an  attribute (Diagram  1) then  you should
> return  a copy  object,  and perhaps,  as  a favor  to  the caller,  a
> mutableCopy.
>
> Returning  a  pointer  to  one  of  your  attribute  is  a  breach  of
> encapsulation.

The value at the time the accessor is called should be returned. Which
object is used to carry the value isn't interesting, but IMO, it should
be arranged so that the object is autoreleased. If you use a mutable
object internally, you should return a copy; if not, returning the
actual object is OK. Either way, the caller shouldn't try to edit the
object.

> If you consider  you have a relationship with  a value object (Diagram
> 2),  then  of  course you  return  the  object  with which  you're  in
> relationship with:
[snip code]
> and there  is no reason  to do anything  further.

True.

> Of course,  in that
> case, you must accept that the returned object may be edited (it could
> be a mutable object after all).

Not necessarily. Even if the object is mutable, the caller shouldn't
automatically assume that it's allowed to edit it. However, in most
cases it could.

> >From the point of view of the caller,
> 
>        NSString* title=[stuff title];
>        NSLog(@"title= %@\n",title);
>        [stuff setTitle:@"New title"];
>        NSLog(@"title= %@\n",title);
> 
> without further information you could as well expect to get as output:
> 
>         title= Old title
>         title= New title

I'd expect the call to -title to return the value at the time it is
called, autoreleased and in such a way that it stays the same. This does
depend on how you define things, but for something like -setTitle: and
-title, I'd expect the value to be the primary thing, not the objects.

[snip]
> Therefore,  we  are  either:
> 
>    - in a  case where  we have attributes,  encapsulated in  the owner
>      object, and in this case we  keep a copy in the settor and return
>      a copy in the gettor,

And the copy is autoreleased.

>      hence  the  caller has  no  worry  about  the returned  attribute
>      values: they belong to it.
> 
>    - or  in a  case where  we have  relationships with  external value
>      objects, and  in this case the  settor retains it  and the gettor
>      just returns the reference to the value object.

True.

>      and here we have the problem in multithreaded programs, where the
>      target of  the relationship may  be released after the  return of
>      the "gettor" and before the caller has time to retain it.

True. In this case the callers will have to ensure that things stay
consistent themselves.

{snip]
>  - (void) setTitle:(NSString *) aString
>    Takes a copy of aString as the title of the window.
>    Update the window to display this new title.
> 
>  - (NSString *) title
>    Returns a copy of the last title set to the window.

Agreed, mostly. In this case we're interested in the value. However,
unless you're using a mutable string internally, 'return [[title copy]
autorelease]' and 'return [[title retain] autorelease]' are equivalent.
Either way, the returned object is autoreleased for the caller.

> However, in the case of the contentView, for example, where we have as
> OpenStepSpecifications:
> 
>  - (id) contentView
>     Returns the NSWindow's content view.
> 
>  - (void) setContentView: (NSView *) aView
>     Makes  aView  the NSWindow's content view.

Yes. In this case we're interested in the object.

[snip]
> In those cases, a return([_contentView retain]autorelease]); would be
> useful, and the GNUstep Documentation could say:

Actually, in this case I don't think that it should do that (always the
opposite :). Then again, contentView is kindof tricky. But eg. NSArray
shouldn't mess with the objects it contains. It merely contains the
objects for the user. If the user wants to access it from several
threads, the user's responsible for locking around calls and
retaining/releasing properly.

- Alexander Malmberg



reply via email to

[Prev in Thread] Current Thread [Next in Thread]