Property attributes in custom setters/getter - iphone

If I create property, for example:
#property NSString *selectedSubProductId;
and create setter and getter:
- (NSString *)selectedSubProductId {}
- (void)setSelectedSubProductId:(NSString *)value_ {}
XCode says that "Deault property attribute 'assign' not appropriate for non-gc object". Do attributes have any meaning in this case? Does it matter if i make them copy or assign or are they only cue for #synthesize to create desired methods? If so, how should I disable the warnings?

If it is object, you should use retain/copy property modifier.
For example:
#property (nonatomic, retain) NSString *selectedSubProductId;
If the modifiers are missing, assign modifier is enabled by default. But it is only valid for scalar (int, float...) or struct.
You may get more details in Apple Documentation

That warning says that you are using a default property atribute (assign) because you forgot to say how do you want to hold your object.
If you want to "remove" the warning use a retain/copy property:
#property (copy) NSString *selectedSubProductId;
However, in Strings you should use copy. For more information please visit this question on stackoverflow.

Related

Are private variables in Objective-C strong?

So searching around Stack Overflow this seems to be how to make private variables in Objective-C:
#interface ClassName()
{
#private
NSArray* private;
}
#property (strong, nonatomic) NSArray* public;
#end
Now this is where I get confused. The property is declared as (strong, nonatomic), but the private variable has nothing of the sort. So how does arc know if it's strong or not?
Instance variables are __strong by default.
From Apple's ARC Transition Guide, regarding variables (presumed to include instance variables):
__strong is the default
and later:
With ARC, instance variables are strong references by default—assigning an object to an instance variable directly does extend the lifetime of the object
This holds until the property is connected to the ivar via #synthesize. At this point, the ownership qualifier of the property takes precedence. However, if you declare a property as anything but strong, and then implement both the setters and getters by hand, you'll have to manually declare the backing ivar's ownership qualifier as well.
In the case of a property, the ownership of the associated instance variable is implied by the ownership of the property:
See http://clang.llvm.org/docs/AutomaticReferenceCounting.html:
If a property is synthesized, then the associated instance variable is
the instance variable which is named, possibly implicitly, by the
#synthesize declaration. If the associated instance variable already
exists, then its ownership qualification must equal the ownership of
the property; otherwise, the instance variable is created with that
ownership qualification.
Generally, Objective-C objects are by default strong:
If an object is declared with retainable object owner type, but
without an explicit ownership qualifier, its type is implicitly
adjusted to have __strong qualification.
Note that since the LLVM 4.0 compiler (Xcode 4.4), the #synthesize statement and the associated instance variable is created automatically, so you need only to declare the property.
The qualifiers on #property specify the behavior of the synthesized setter and other ARC inserted code. Variables themselves aren't really strong or not, they're just memory locations. So you've got it coded strong right now.
The way to make it private (and strong) is to declare it strong in a category inside .m file.
// .h
// nothing
// .m
#interface ClassName()
#property (strong, nonatomic) NSArray* myStrongPrivateProperty;
#end
// that's it

what is the difference between a readwrite property and a nonatomic assign property?

I have seen readwrite on int, BOOL etc same as nonatomic, assign.
I am some what confused on this. I do know that on non native objects, we typically do nonatomic, retain.
Here's the short answer:
atomic vs nonatomic primarily ensures that complete values are returned from synthesized getters and that complete values are written by synthesized setters (atomic is default.)
readwrite vs readonly determines whether a synthesized property has a synthesized accessor or not (readwrite has a setter and is the default, readonly does not).
assign vs retain vs copy determines how the synthesized accessors interact with the Objective-C memory management scheme:
assign is the default and simply performs a variable assignment
retain specifies the new value should be sent -retain on assignment and the old value sent -release
copy specifies the new value should be sent -copy on assignment and the old value sent -release.
After reading so many Articles, SO posts and made demo apps to check Variable property attributes, I decided to put all the attributes information together
atomic //default
nonatomic
strong=retain //default
weak= unsafe_unretained
retain
assign //default
unsafe_unretained
copy
readonly
readwrite //default
so below is the detailed article link where you can find above mentioned all attributes, that will defiantly help you.
Many thanks to all the people who give best answers here!!
Variable property attributes or Modifiers in iOS
retain = strong
it is retained, old value is released and it is assigned
retain specifies the new value should be sent -retain on assignment and the old value sent -release
retain is the same as strong.
apple says if you write retain it will auto converted/work like strong only.
methods like "alloc" include an implicit "retain"
Example:
#property (nonatomic, retain) NSString *name;
#synthesize name;
assign
assign is the default and simply performs a variable assignment
assign is a property attribute that tells the compiler how to synthesize the property's setter implementation
I would use assign for C primitive properties and weak for weak references to Objective-C objects.
Example:
#property (nonatomic, assign) NSString *address;
#synthesize address;
readonly
declaring your property as readonly you tell compiler to not generate setter method automatically.
Indicates that the property is read-only.
If you specify readonly, only a getter method is required in the #implementation block. If you use the #synthesize directive in
the #implementation block, only the getter method is synthesized. Moreover, if you attempt to assign a value using the dot syntax,
you get a compiler error.
Example:
#property (nonatomic, readonly) NSString *name;
#synthesize name;
readwrite
setter and getter generated.
Indicates that the property should be treated as read/write.
This attribute is the default.
Both a getter and setter method are required in the #implementation block. If you use the #synthesize directive in the implementation
block, the getter and setter methods are synthesized.
Example:
#property (nonatomic, readwrite) NSString *name;
#synthesize name;
readwrite means that both a getter and a setter exist; the opposite is readonly. Normally the only time you'd explicitly declare a property readwrite is in a class extension for a class where the public interface declares the property readonly — so that it's publicly read-only, but internally you can both get and set.

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.

Do I use retain or copy in my singleton?

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

How can I make a weak reference to a parent object when using properties?

I am not sure about it. Would I do that this way?
#property(nonatomic) MyParentObject *parentObject;
Note that I just left out the retain Keyword. Or would I have to write the Setter by myself?
Instead of retain, you can use the assign attribute (which is actually the default). assign will prevent your generated setter from retaining or releasing parentObject. For example:
#property (assign, nonatomic) MyParentObject *parentObject;
For a list of all attributes that can be used by Objective-C properties, take a look at the documentation.