0

I know that when using ARC and you have an NSString property, you do @property(nonatomic, copy) just as you would MRC. But I'm wondering, after I converted my project to ARC, I still have this in my initializer method:

_someString = [someStringParameter copy]

Is this a bug? Or even with ARC, do I still need to explicitly say "copy" ? Or should I just do:

self.someString = someStringParameter

and all will be OK? Bit confused here...

Ser Pounce
  • 14,196
  • 18
  • 84
  • 169

2 Answers2

2

You'd never use self.someString = anything in your initialiser. The dot notation is a method call. You shouldn't call methods on classes that aren't fully instantiated yet. Most demonstrable failure case: a subclass overrides setSomeString: — where is it in its init when that method is called?

ARC will handle proper retains and releases on instance variables but can't automatically do copies — e.g. there are __strong and __weak modifiers but no __copy. So you still need explicitly to copy when doing a direct instance variable assignment.

Tommy
  • 99,986
  • 12
  • 185
  • 204
  • Thanks for the response. I never override the property methods so that's why I do it. What I come across sometimes is I have to call a method from the initializer that accesses properties, and I also have to call that same method from within the code somewhere. How do you handle that situation? Should the properties in said method be dot notation, or do direct access to variable? – Ser Pounce Aug 27 '13 at 00:14
  • The problem is that even if you personally don't override property accessors, writing your code so as not to allow them to be overridden introduces constraints that can't adequately be expressed in the interface or elsewhere. So it's considered bad practice. Calling consequential methods can invoke the exact same problems so it is formally problematic. – Tommy Aug 27 '13 at 00:17
1
_someString = [someStringParameter copy];

Is this a bug?

No.

Or even with ARC, do I still need to explicitly say "copy" ?

Absolutely.

You're assigning the instance variable by copy and it's perfectly legit under ARC. As opposed to that, doing just:

_someString = someStringParamenter;

will cause ARC to automatically retain (not copy) it, resulting in something like

_someString = [someStringParameter retain];

This happens because under ARC variables have an implicit __strong identifier unless specified otherwise.


self.someString = someStringParameter

This is right, and both under ARC and MRC you'll get the object to be copied if you provided the copy attribute in the property declaration.

That said, it's still a bad idea to use accessor methods in initializers, since they may have unwanted side effects in case you have a custom implementation for them. Check out this answer on the subject: Should I refer to self.property in the init method with ARC?

Community
  • 1
  • 1
Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
  • Thanks for the response. I never override the property methods so that's why I do it. What I come across sometimes is I have to call a method from the initializer that accesses properties, and I also have to call that same method from within the code somewhere. How do you handle that situation? Should the properties in said method be dot notation, or do direct access to variable? – Ser Pounce Aug 27 '13 at 00:14
  • If you are **absolutely positive** that the accessor methods you're calling don't have any side effects, you can safely call them from the initializers. Anyway I wouldn't get used to it, since it's a bad practice and it's easy to make mistakes and to introduce awful bugs. If you can split your logic that would be better, since initializing and object should be conceptually separated than anything else you do afterwards. – Gabriele Petronella Aug 27 '13 at 00:18
  • I guess it happens in the pattern where I need to reload something. I load it in the initializer, then if user makes in app purchase, need to reload again. – Ser Pounce Aug 27 '13 at 00:21
  • If you really cannot separate the logic in that sense, I'd fly safely and use instance variable directly in such "shared" methods. Remember to copy the objects whenever needed. – Gabriele Petronella Aug 27 '13 at 00:22