Objective C - Custom setter with ARC?
19,920
Solution 1
The strong
takes care of itself on the ivar level, so you can merely do
- (void)setMyObject:(MyObject *)anObject
{
_myObject = anObject;
// other stuff
}
and that's it.
Note: if you're doing this without automatic properties, the ivar would be
MyObject *_myObject;
and then ARC takes cares of the retains and releases for you (thankfully). __strong
is the qualifier by default.
Solution 2
Just to sum up the answer
.h file
//If you are doing this without the ivar
@property (nonatomic, strong) MyObject *myObject;
.m file
@synthesize myObject = _myObject;
- (void)setMyObject:(MyObject *)anObject
{
if (_myObject != anObject)
{
_myObject = nil;
_myObject = anObject;
}
// other stuff
}
Related videos on Youtube
Author by
aryaxt
Updated on December 10, 2020Comments
-
aryaxt over 3 years
Here is how I used to write a custom retained setter before:
- (void)setMyObject:(MyObject *)anObject { [_myObject release], _myObject = nil; _myObject = [anObject retain]; // Other stuff }
How can I achieve this with ARC when the property is set to strong. How can I make sure that the variable has strong pointer?
-
Tricertops about 11 yearsIs this really how you used to write setters? I think you should add an
if
statement checking, ifanObject
is not the same as_myObject
. If they both reference the same object with retain count 1, you deallocates the object on first line and crash on second. -
Tricertops about 11 yearsSorry about the crash, you are right, you are nullifying it. You are almost right with that second part, but there is one case: the only place where the object is referenced is this property itself. Very simplified:
self.title = self.title;
, but this may happen in more complex situation. You don't know where the object came from, you assign it to property, and boom it is lost. -
Tricertops about 11 years… and not just it is lost, but in this specific case the code will crash. On release, it may get deallocated, you nullify ivar, but then retain deallocated object – crash.
-
aryaxt about 11 years@iMartin I couldn't get it to crash using your example, but you are right it may cause a crash, so it's best to do the equal check
-
Töre Çağrı Uyar almost 11 years@aryaxt, actually, you are not wrong. If the only place an object is referenced is a property and you set another object to that property first object should be deallocated anyway.
self.title = self.title;
won't crash but not because of the setter, it's because of the getter. Getter should always return an autoreleased object, a getter never should assume it will have object longer than receiver needs to. Returning an object in a getter without retaining and autoreleasing it again is a mistake. That's exactly why above code won't crash.
-
-
Alex Gray almost 12 yearswhat does your
@synthesize
look like with (both) of these options? -
Dan Rosenstark almost 12 years@alexgray your synthesize generally looks like
@synthesize myObject = _myObject
to keep the names of the iVar and property different. See here (stackoverflow.com/questions/822487) for whether that's a good idea. -
Dan Rosenstark over 11 years@alexgray UPDATE with the new stuff (um, LLVM 4.0 or Xcode 4.4 or something) you don't have to write synthesize, IF you were lucky enough to ignore all the know-it-alls on SO and use the underscore as a prefix.
-
ma11hew28 over 11 yearsI don't think you need
__strong
because it's inferred if left out. -
Dan Rosenstark over 11 yearsThanks @MattDiPasquale... fixed.
-
Robert Nall over 11 yearsI may be missing something here, but I'm confused by the ivar you have listed for non-auto properties—wouldn't the ivar for this situation be
MyObject *_myObject;
? -
Dan Rosenstark over 11 years@RobertNall you can call the ivar whatever you want, but you're right. I've adjusted the answer.
-
Alec about 11 years@Yar thanks for the answer. Now what if the
myObject
property wascopy
instead ofstrong
? Do you need tocopy
it in the custom setter via_myObject = [anObject copy];
with ARC? -
Dan Rosenstark about 11 yearsIf you're doing the setter (a custom setter), then you have to do the copy as you suggest. If you don't, then the copy is done automatically for you. Copy implies strong ownership, so if you're doing the ivar, it should be like it is here (with no specification it would be
strong
). See here for more confusion: clang.llvm.org/docs/AutomaticReferenceCounting.html and search on "copy implies __strong ownership" -
Töre Çağrı Uyar almost 11 yearsChecking is unnecessary, you won't get a performance increase or reliability with checking like
_myObject != anObject
, you can only get a little bit performance decrease. Also setting iVar tonil
is unnecessary, too. Won't get any reliability with_myObject = nil;
, too.