Pergunta

I have 2 questions.

First - Are string declared as such in obj-c

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *city;

Are those (nonatomic, copy) right or should I use (nonatomic, strong), or something else ?

Second - If I want to set custom initializer for above strings do I use

-(id)initWithName:(NSString *)n andCity:(NSString *)c
{
    self = [super init];
    if (self) {
        self.name = n;
        self.city = c;
    }
}

or should I use:

-(id)initWithName:(NSString *)n andCity:(NSString *)c
{
    self = [super init];
    if (self) {
        self.name = [n copy]
        self.city = [c copy];
    }
}

As I can see both ways seem to work for both questions but I'm sure one is more correct than the other, so I wanted to ask which should I use to write correct code in further projects.

Thanks.

Foi útil?

Solução 2

First - it doesn't really matter if you use copy or strong. Personally i prefer to copy strings rather than retain them

Second - `

-(id)initWithName:(NSString *)n andCity:(NSString *)c

   {
      self = [super init];
       if (self) {
          self.name = n;
          self.city = c;
  }
}`

You don't need to use copy message once more cause your properties will copy n and c. If you apply your second piece of code you'll copy n and c twice and have a memory leak

Outras dicas

You want to use copy for value-semantic-typed properties. (Of which NSString is always one.) Otherwise, I can pass you an instance of NSMutableString and then change it out from under you after the fact. Immutable objects will implement -copyWithZone: by doing return [self retain]; so as to not actually create a second copy when it's not needed. See also: NSString property: copy or retain?

In terms of your -init method, you want to avoid using the property setters like you have since they could be overridden in a subclass to do something unforeseeable by your class. So assuming default auto-ivar-synthesis naming pattern, you would want to do this:

-(id)initWithName:(NSString *)n andCity:(NSString *)c
{
    if (self = [super init])
    {
        _name = [n copy];
        _city = [c copy];
    }
    return self;
}

It's a subtle thing, and it won't often be a problem, but if you continue to use inherently-virtual property setters in -init and -dealloc methods, over a long enough timeline, you will get burned by this (can you tell I've been burned by this?)

As for leaked memory, if you're using ARC, doing something like self.foo = [bar copy]; when foo is a copy property will result in copy getting called twice, and potentially two copies being made, but ARC should take care of properly releasing the redundant/intermediate copy, and there should not be a memory leak.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top