8

My property was declared in my NSManagedObject class with name "newPrice", which leads to "zombie object". After some hours of debugging I figured out that there is problem with method which is releasing this object but not retaining it. After renaming this property to "priceNew" everything goes well. I don't understand why this is causing problem.

Declaration of property:

@property (nonatomic, retain) NSNumber * newPrice;

This call causing problem:

[self setPieceStateWithPrice:self.action.newPrice];

After passing renamed argument like self.action.priceNew everything goes well...

fillky
  • 591
  • 2
  • 6
  • 18

2 Answers2

10

Don't do that.

In Objective-C naming conventions, methods whose names begin with new are expected to return a retained object. With ARC, that naming convention becomes a requirement. That means that a normal, ARC-compiled method should never start with the name new because the compiler will assume that it already has a retain count of 1.

To quote the docs:

You own any object you create

You create an object using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” (for example, alloc, newObject, or mutableCopy).

Todd Lehman
  • 2,880
  • 1
  • 26
  • 32
Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • 1
    Curious whether this convention is still a best practice in Swift. Functionally, prefixing a property name with `new` appears to be completely safe in Swift (no effect on retain count and no issues compiling). Any thoughts? – Kyle Clegg Mar 04 '16 at 18:16
  • is not safe in Swift if you declare a variable as dynamic! – Claudio Barbera Feb 15 '17 at 13:59
  • "When returning from such a function or method, ARC retains the value at the point of evaluation of the return statement, before leaving all local scopes". According what is said in [Clang](http://clang.llvm.org/docs/AutomaticReferenceCounting.html#retained-return-values), the value should be retained before it gets returned from `newPrice`. So the assertion that it has retain count of 1 should be correct. Which means it actually should not be over-released. – CopperCash Apr 21 '19 at 08:38
  • if i were to use a variable 'newsId', will that cause an issue? just wondering – Jerrin Sep 18 '19 at 09:16
  • @Duncan C Is it OK to name a Class with new prefix ,e.g 'NewRouteCenter'? – ximmyxiao Nov 16 '22 at 07:22
  • I don't think these rules apply to Swift. And it is only when an Objective-C function name begins with "new" and returns a reference object that it is an issue. Class names and variable names should not be affected (Disclaimer: It's been a long time since I looked at this. My memory of the specifics is getting pretty hazy.) – Duncan C Nov 16 '22 at 16:16
  • Was naming a property in NSManagedObject with prefix `new`. All hell broke loose. DO. NOT. DO. THIS. – Maciej Stramski Dec 16 '22 at 10:35
  • @MaciejStramski was this in a purely Swift app? – Duncan C Dec 16 '22 at 14:02
  • @duncanc yes. Purely swift without objc bridging. Property was a NSManaged one with connection to CoreData model. – Maciej Stramski Dec 17 '22 at 15:45
  • Yikes. Seems like that memory management convention should have been left out of Swift. – Duncan C Dec 17 '22 at 21:52
6

Properties have methods automatically synthesized for them. So, having a property implies have a method with the same name.

Methods which begin with alloc, copy, init, mutableCopy, and new have special assumptions about how they handle memory. Unless you have a very good reason, you should avoid these prefixes.

From Clang 3.5 documentation | Objective-C Automatic Reference Counting | Retained return values

A function or method which returns a retainable object pointer type may be marked as returning a retained value, signifying that the caller expects to take ownership of a +1 retain count.

Methods in the alloc, copy, init, mutableCopy, and new families are implicitly marked attribute((ns_returns_retained)). This may be suppressed by explicitly marking the method attribute((ns_returns_not_retained)).

Community
  • 1
  • 1
Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117
  • I didn't know about that compiler switch. Thanks for sharing that nugget. (Voted back when you first posted it.) It looks like the way this switch is used in Apple's code is to prefix the method with `NS_RETURNS_RETAINED`. – Duncan C Mar 19 '15 at 11:31
  • @Jeffery Thomas Is it OK to name a Class with new prefix ,e.g 'NewRouteCenter'? – ximmyxiao Nov 16 '22 at 07:23
  • @ximmyxiao while I don't think it will cause an issue, I would never do that. Why risk causing a hard to find bug? – Jeffery Thomas Nov 18 '22 at 19:46
  • @JefferyThomas OK ~~got it ~thanks alot , In fact , I have created a class whose name is prefixing with "New" years ago , And if it will not cause memory problem, I will feel more safe:) And I will refactor it in the future – ximmyxiao Nov 21 '22 at 02:45