Do I use retain or copy in my singleton? - iphone

I read somewhere that with NSString in an object, one has to use copy instead of retain. Can someone explain if this is correct and why?
For example I have the following declaration for my singleton:
#import <foundation/Foundation.h>
#class FaxRecipient;
#interface MyManager : NSObject {
NSString *subject;
NSString *reference;
NSString *coverSheet;
FaxRecipient *faxRecipient;
}
#property (nonatomic, retain) NSString *test1;
#property (nonatomic, retain) NSString *test2;
#property (nonatomic, retain) NSString *test3;
#property (nonatomic,retain) FaxRecipient *faxRecipient;
+ (id)sharedManager;
#end

I think "has to" in the sense of must is a little strong. You can use either copy or retain, but you should generally use copy for your NSString* properties because:
You usually don't want a string property to change under your nose;
NSMutableString is a subclass of NSString, so it's entirely possible that someone might set your NSString* property to point to a mutable string, thus creating the potential for the string to be changed while you're using it;
For immutable classes like NSString, copy operations end up just retaining the original object anyway.
Considering those three points, it's hard to think of a good reason to use retain instead of copy for your NSString properties.

prefer copy. it does not matter whether your class is or is not a singleton.
i wrote a fairly lengthy explanation for this, which details mutable and immutable types here:
NSMutableString as retain/copy

You can also use copy instead of retain. I use copy for NSString. There is good discussion on this topic. Here is a stackoverflow post NSString Copy or Retain?

You could use either,In both cases you will be owner of the objects and need to be released in dealloc.
Difference between copy and retain .
retain :--> It just increase the retain count on the exist object.
copy :--> it crate the new object for your property
In both cases: you will have the ownership of objects.
Read Apple memory management concept.
# Claus Broch: From Apple Documentation
You take ownership of an object if you
create it using a method whose name
begins with “alloc”, “new”, “copy”, or
“mutableCopy” (for example, alloc,
newObject, or mutableCopy), or if you
send it a retain message.

You should use the retain value in this instance. The reason for this is that
1. you don't want the object to be deallocated
2. you are most likely going to want to change the value of the NSString at some point
Using the copy attribute is basically saying that the value of your NSString should not change without warning. i.e. it will stop the value of the NSString being set and retrieved at the same time.
For this implementation, you should use retain, or at least thats my understanding. For more look here: http://cocoawithlove.com/2010/06/assign-retain-copy-pitfalls-in-obj-c.html

Related

get the value of a NSString variable

I have a weird problem.
pictureLink is a global variable declared in .h
NSString *pictureLink;
}
#property(retain,nonatomic) NSString *pictureLink;
i wrote this code
NSString * myPictureUrl=[NSString stringWithFormat:#"http://mywebsite.com/uploads/%#.jpg",hash];
pictureLink=myPictureUrl;
I have a strange result, it must be a pointer
Or
pictureLink=[NSString stringWithFormat:#"http://mywebsite.com/uploads/%#.jpg",hash];
i have EXC_BAD_ACESS error
It's memory management fault, you're not retaining myPictureUrl in your code.
[NSString stringWithFormat:#"http://mywebsite.com/uploads/%#.jpg",hash]; returns an autoreleased value, so you have two options:
pictureLink=myPictureUrl; should look like [self setPictureLink:myPictureUrl];.
do a [myPictureUrl retain];, and don't forget to release it later.
Consider using ARC (Automatic Retain Counting) for you project. With ARC the compiler takes care of retain counts so you don't have to, in fact aren't allowed to. There is a refactoring that will convert a current project.
You are bypassing your #property by calling directly the variable, so no magic provided by your #property settings is done, like retain and release.
you need to do self.pictureLink to use the #property.
To avoid the temptation of accessing directly my variable I do the following
NSString *theProperty
}
#property (nonatomic, retain) NSString *property;
and
#synthesise property = theProperty;
That way if I go around the #property I really, really wanted to do it.
But you need a very, very, very good reason to do so, and event then, it may not be a good enough reason.

Private properties and methods in Objective-C

In looking at one of Apple's examples, in the TableViewController.m, they have this:
// Private TableViewController properties and methods.
#interface TableViewController ()
#property (nonatomic, retain) NSMutableArray* sectionInfoArray;
#property (nonatomic, retain) NSIndexPath* pinchedIndexPath;
#property (nonatomic, assign) NSInteger openSectionIndex;
#property (nonatomic, assign) CGFloat initialPinchHeight;
... more properties and methods
#end
#implementation TableViewController
... usual stuff
I'm wondering why they put these properties in the .m file and how this is private. It seems like anyone who imports the TableViewController.m file can use these properties and methods right? Why not use the #private in the .h file?
What they're doing is declaring a category on the class, but since this is done in the .m file, the effect is that those methods are "invisible".
This doesn't mean however that those methods cannot be called from the outside. This is due to the fact that there is no real privacy in objective c, because we're dealing with messages, not method calls. This means you can send an object a message even if you do not know if that object actually implements the method you're trying to call. The receiving object will determine at runtime if it can handle this call, maybe it will even forward it, and it will make no difference whether the method was known to the calling object or not.
This is one of the reasons why it is possible to call private APIs and get rejected for it.
They're not private. They're anonymous properties, since they're part of an anonymous category.
One of the things properties are good for is putting the memory management semantics for an owned object in a single place. Consider this:
#property (nonatomic, assigned) NSString *assigned;
#property (nonatomic, copy) NSString *copied;
#property (nonatomic, retain) NSString *retained;
In all three cases, you can assign to them like this without knowing what their memory semantic is:
self.assigned = stringParameter; // assigns to instance variable
self.copied = stringParameter; // copies, assigns copy to instance variable
self.retained = stringParameter; // retains, assigns to instance variable
And in all three cases, you can free clean up using the same code:
self.assigned = nil; // this just nils the instance variable
self.copied = nil; // releases copy in ivar, nils instance variable
self.retained = nil; // releases ivar (same as original object),
// nils instance variable
This is why you'll often see local properties: It lets the coder skip writing all the memory management logic each time they want to assign to the instance variable. This is a major advantage in that you can change the memory management logic throughout the entire class just by changing the #property.
Another use of anonymous properties is to extend a property declared as readonly to outside code as read/write to the class itself.
In .h:
#property (nonatomic, readonly, retain) NSError *lastError;
In .m, in an anonymous category:
#property (nonatomic, readwrite, retain) NSError *lastError;
Elsewhere in .m code:
self.lastError = error;
Again, this is mostly done for memory management reasons.
An example, that pertains to either use of anonymous properties.
Here's what each assignment to a _lastError instance variable looks like without properties.
Assume we have a NSError called _lastError defined in the .h file.
With retain:
[_lastError release];
_lastError = [error retain];
With copy:
[_lastError release];
_lastError = [error copy];
With assign:
_lastError = error;
In the first two cases, you need this in your dealloc:
[_lastError release];
But in the last case, you must put nothing in the dealloc or you'll get a crash.
So let's add what we need to use a property instead:
Add this in an anonymous category:
#property (nonatomic, readwrite, retain) NSError *lastError;
Add this in the #implementation:
#synthesize lastError = _lastError;
Note, also, that at this point on the "modern" Cocoa runtime (64 bit Mac or iOS), you can remove the NSError *_lastError from your header. The compiler can figure out you want that based on the #synthesize.
Here's how that changes our code:
Each assignment:
self.lastError = error; // works regardless of storage specifier
In daelloc:
self.lastError = nil; // works regardless of storage specifier
AFAIK
a) You can not mark properties as #private in .h - this works only for ivars.
b) You will not be able to reference your class if you just import .m file (without interface definition in .h file). and if you do - you will get duplicate symbols during linking.
c) So yes these properties are private in the sense they are not accessible as regular properties from outside - these properties are accessible only using explicit messages - however you'll get warnings from compiler in this case or you could use KVC
First, you typically cannot import an .m file - not without numerous compiler/linker errors. Second, the properties are private so that Apple is free to change them in subsequent releases.
Yes, you can get to them via reflection. But that's a slippery slope, blah blah proceed at your own risk, will break in later versions blah blah reflection bad unless you know exactly what you're doing.
There are no private methods or variables in objective c, the #private flag is mainly there just so when other developers look at it, they know it's supposed to be private. What your seeing in the apple code is an example of a category, a way to fake private methods and variables in objective c. Because outside classes will import the .h file only, they will never see the added methods and variables in the .m file.
Using an anonymous category black boxes internal properties and methods that other classes should not know about. Although the compiler doesn't know about them when this class is referenced from other classes, you could technically access any of these properties from that other class using key value coding.
you can't import the implementation file TableViewController.m, Only the .h file of TableViewController could be imported,
Although, you could have the reference of these property outside your TableViewController class with a warning that shows the "not respond" note.

Is a private synthesized property an oxymoron?

After going through a beginner's iPhone developer book and reading sample code online, I've noticed that most Objective C programmers synthesize nearly every instance variable. Some variables are convenient to snythesize, but most should not when honoring the object oriented principle of encapsulation. The worst are synthetized properties marked as private. A C++ programmer trying to use someone else's code will read the public fields and methods in the header file. They will skip the private variables. This C++ programmer will not know that you intended the private properties to be used in some meaningful way.
Take a look at this sample template on lazy table image loading provided by Apple:
Header
#interface ParseOperation : NSOperation <NSXMLParserDelegate>
{
#private
id <ParseOperationDelegate> delegate;
NSData *dataToParse;
NSMutableArray *workingArray;
AppRecord *workingEntry;
NSMutableString *workingPropertyString;
NSArray *elementsToParse;
BOOL storingCharacterData;
}
Source
#interface ParseOperation ()
#property (nonatomic, assign) id <ParseOperationDelegate> delegate;
#property (nonatomic, retain) NSData *dataToParse;
#property (nonatomic, retain) NSMutableArray *workingArray;
#property (nonatomic, retain) AppRecord *workingEntry;
#property (nonatomic, retain) NSMutableString *workingPropertyString;
#property (nonatomic, retain) NSArray *elementsToParse;
#property (nonatomic, assign) BOOL storingCharacterData;
#end
#implementation ParseOperation
#synthesize delegate, dataToParse, workingArray, workingEntry, workingPropertyString, elementsToParse, storingCharacterData;
Now I know this is not C++ and we shouldn't assume all C++ practices should be honored in Objective C. But Objective C should have good reasons to stray away from general programming practices.
Why are all the private ivars synthesized? When you look at the project as a whole, only NSMutableArray *workingArray is used by outside classes. So none of the other ivars should have setters and getters.
Why are very sensitive ivars synthesized? For one, now that id delegate has a setter, the user of this object can switch the delegate in middle of the XML parsing, something that doesn't make sense. Also, NSData *dataToParse is raw XML data retrieved from the network. Now that it has a setter, the user of this object can corrupt the data.
What's the point of marking everything private in the header? Since all ivars are are synthesized to have getters/setters, they are effectively public. You can set them to anything you want and you can get their value whenever you want.
I follow the idiom modeled by this example in many of my classes, so I can try to explain my own justification for this practice.
The properties in this example are declared in a class extension in the .m file. This makes them effectively private. Any attempt to access these properties from another class will cause a "Property not found" error upon compilation.
For developers coming from other languages, it may seem strange to synthesize getters and setters for private instance variables. Indeed, there is only one reason why I do this. When used consistently, synthesized properties can simplify memory management and help avoid careless mistakes that can lead to bugs. Here are a couple of examples:
Consider this:
self.workingPropertyString = [NSMutableString string];
versus this:
workingPropertyString = [[NSMutableString string] retain];
Many developers would claim that these two assignments are functionally equivalent, but there's an important difference. The second assignment leaks memory if workingPropertyString was already pointing at a retained object. To write code functionally equivalent to the synthesized setter, you'd have to do something like this:
NSMutableString *newString = [NSMutableString string];
if (workingPropertyString != newString) {
[workingPropertyString release];
workingPropertyString = [newString retain];
}
This code avoids leaking any existing object that the instance variable may be pointing to, and it safely handles the possibility that you may be re-assigning the same object to the instance variable. The synthesized setter does all of this for you.
Of course we can see that (workingPropertyString != newString) will always be true in this case, so we could simplify this particular assignment. In fact in most cases you can probably get away with a simple direct assignment to an instance variable, but of course it's the exceptional cases that tend to create the most bugs. I prefer to play it safe and set all my object instance variables through synthesized setters. All my instance object assignments are simple one-liners that look like this:
self.foo = [Foo fooWithTitle:#"The Foo"];
or this:
self.foo = [[[Foo alloc] initWithTitle:#"The Foo"] autorelease];
This simplicity and consistency gives my feeble brain less stuff to think about. As a result I almost never have bugs related to memory management. (I'm aware that the autorelease idiom could theoretically consume excessive memory in a tight loop, but I have yet to encounter that issue in practice. If I ever do, it's a simple case to optimize.)
One other thing I like about this practice is that my dealloc methods all look like this:
- (void)dealloc {
self.delegate = nil;
self.dataToParse = nil;
self.workingArray = nil;
self.workingEntry = nil;
self.workingPropertyString = nil;
self.elementsToParse = nil;
[super dealloc];
}
EDIT: Daniel Dickison pointed out some
risks to using accessors in dealloc
that I hadn't considered. See the
comments.
where every object property is simply set to nil. This simultaneously releases each retained property while setting it to nil to avoid certain crashes due to EXC_BAD_ACCESS.
Note that I've set self.delegate = nil; even though that property was declared as (nonatomic, assign). This assignment wasn't strictly necessary. In fact, I could do away with properties for my (nonatomic, assign) objects altogether, but again I've found that applying this idiom consistently across all my instance variables gives my brain less to think about, and further reduces the chance that I'll create a bug through some careless mistake. If necessary I can simply flip a property from (nonatomic, assign) to (nonatomic, retain) without having to touch any memory management code. I like that.
One could also use consistency as an argument for synthesizing properties for private scalar variables, as your example has done in the case of BOOL storingCharacterData;. This practice ensures that every instance variable assignment will look like self.foo = bar;. I don't usually bother to create private scalar properties myself, but I can see some justification for this practice.
Why are all the private ivars
synthesized? When you look at the
project as a whole, only
NSMutableArray *workingArray is used
by outside classes. So none of the
other ivars should have setters and
getters.
No real need; if you are going to access all the ivars directly anyway, there is no need for #synthesize.
Why are very sensitive ivars
synthesized? For one, now that id
delegate has a setter, the user of
this object can switch the delegate in
middle of the XML parsing, something
that doesn't make sense. Also, NSData
*dataToParse is raw XML data retrieved from the network. Now that it has a
setter, the user of this object can
corrupt the data.
None of the setter/getters are publicly declared. If a client of the class wanted to corrupt things by switching the delegate in the middle, they'd have to break encapsulation to do so.
So, ultimately, a non-issue.
What's the point of marking everything
private in the header? Since all ivars
are are synthesized to have
getters/setters, they are effectively
public. You can set them to anything
you want and you can get their value
whenever you want.
Note that there is no need to even declare the ivars in that example; the compiler will automatically synthesize them based on the #property declaration.
Traditionally, #private protected against someone diddling the ivar directly from externally to an instance of the class.
Note that anInstance->ivar or self->ivar is almost never used (and, when used, it is almost always for the wrong reason). There are uses for it, but it is rare.

In which situations would an object not be key-value coding compliant?

Currently I'm learning all the stuff around key-value coding.
In the docs they say:
Any object in the key path sequence
that is not key-value coding compliant
for the appropriate key receives a
valueForUndefinedKey: message.
I try to imagine a situation where an object is not key-value coding compliant. How could that happen? When I subclass an UIView, that's obviously compliant, right? But when I just make my own object with NSObject as superclass, how's that? And when I make a class with no superclass, then for sure this is not k-v compliant?
If you read carefully, you'll see it says "key-value coding compliant for the appropriate key". This means, basically, that you don't have the appropriate KVC methods for the key you asked for. So if I do [[NSString stringWithString:#"foo"] valueForKey:#"dippingSauce"], it will fall through to valueForUndefinedKey: because NSString is not KVC-compliant for the key "dippingSauce" — it doesn't have a dippingSauce instance method or a dippingSauce ivar.
It says "that is not key-value coding compliant for the appropriate key." What that means is that
#interface MyObject : NSObject {
NSString *foo;
NSString *bar;
}
#property (nonatomic, retain) NSString *foo;
#property (nonatomic, retain) NSString *bar;
#end
#interface MyObject
#synthesize foo;
#synthesize bar;
#end
Is compliant for "foo" and "bar", but not "baz."
For simple properties that is all there is to it, by default all NSObject subclasses implement basic KVC. It gets trickier with collections. In order for KVC to work correctly for collections (so you can do things like:
NSArray *people = ... ;
NSArray *firstNames = [people valueForKey:#"firstName"];
It requires you implement certain extra methods. In general the biggest user of that functionality is Cocoa bindings (which is not available on the iPhone) sourced out of CoreData (which generates that additional collection methods automatically anyway), so it still usually handled basically automatically. Generally people don't bother to implement full KVC support for dictionaries or arrays in their objects unless they intend to actually expose them. You can read about compliance in the KVC guide.

Can you help me understand retain counts in cocoa/objective-c?

> .h file:
NSString *myString;
#property (nonatomic, retain) NSString *myString;
> .m file:
self.myString = [[NSString alloc] init];
If i'm not wrong i will end up with an NSString instance with retain count of +2. Right?
I'm curious because Apple's example for Location uses "self." for initialization. Why? I checked and it does show retain count to be +2.
To answer your first question:
Yes, the retain count would be two.
To answer your second question:
The reason for using:
self.myString = x;
which is equivalent to:
[self setMyString:x];
is so that all of the property handling code is properly executed. This includes KVO notifications, and the code that automatically retains x as it is passed in.
If you were to simply set:
myString = x;
in the .m file, you would bypass all of that hidden property setting code, and simply set the myString member variable to a pointer to x.
Mustafa: Yes, you're correct. (The property should be declared as copy, not retain, but that's another matter.)
In your Modification 1, you're setting your instance variable directly to an autoreleased object. This means that at the end of the event loop your locationManager will be released and in this case, you'll then have a reference to a now unused block of memory.
Your Modification 2 looks correct to me, as does the sample code you've started from.