Why give a property both readonly and assign? - objective-c

If assign is a setter, but a property is readonly, then it will not be doing any setting, so why use assign ?
I am getting this from the Apple docs on class extensions. In this page, I get why you'd want a public readonly property, then make it privately readwrite, but then why not omit the assign from the public #interface and just include it in the class extension only?

If you declare a #property multiple times (typically because you declare a public readonly property in the header file, and a readwrite property in an anonymous category in your .m), the memory management schemes have to match.
So if you have this in your .m:
#property (assign, readwrite) NSObject *foo;
Then you need this in your header, and the assign is mandatory:
#property (assign, readonly) NSObject *foo;

If you leave just (nonatomic), the compiler will automatically set the second parameter to assign.

Related

Declare a static property in an Objective-C class interface

I'm defining an Objective-C class:
#interface MyRequest : NSObject
#property (strong, nonatomic, readonly) NSDecimalNumber *myNumber;
#property (strong, nonatomic, readonly) CommConfig *commConfig;
#property (nonatomic, assign, readonly) BOOL debug;
How do I make commConfig a static variable? When I use the 'class' keyword, the compiler gives me the following warning:
Class property 'commConfig' requires method 'commConfig' to be defined - use #dynamic or provide a method implementation in this class implementation
And the constructor doesn't recognize this line anymore:
_commConfig = commConfig
If not implemented by the programmer instance properties are automatically implemented by the compiler - an instance variable allocated and getter and/or setter methods written. Class properties are never automatically implemented, you therefore need to declare the static backing variable and define the getter. In your #implementation add:
static CommConfig *_commConfig;
+ (CommConfig *) commConfig { return _commConfig; }
You can call the backing anything you wish, e.g. to follow a naming convention for global/static variables.
HTH

iOS readonly and retain are mutually exclusive

I want to have a strong readonly property. When I use this code:
#property (strong, nonatomic, readonly) NSString *test;
I get a warning: "Property attributes 'readonly' and 'retain' are mutually exclusive". How can I solve this warning?
Create a property in your continuation category which redefines the variable as readwrite:
#property (strong, nonatomic, readwrite) NSString *test;
Now, publicly the property is read only, but privately you can write it. The compiler will generate the methods you need and allow you to call them.

Objective-C NSCoding and Read-only

Objective C Read-only
I want to change my NSCoding property to read-only.
For example, let’s set the readonly attribute for the lastName property on Person:
Person.h
#interface Person : NSObject
#property NSString *firstName;
#property (readonly) NSString *lastName;
#end
Assignment to readonly property
Okay, so outside code can’t set the property value, But when I tagged the lastName property with the readonly attribute by including (readonly) right after the #property declaration. but I still receive an error like this:
Person.m
#import "Person.h"
#implementation Person
- (void) changeLastName:(NSString *)newLastName;
{
self.lastName = newLastName;
}
#end
Assignment to readonly property
What happens here? Can someone tells me why It doesn’t work.
Thanks.
You need to redeclare it inside the class as readwrite
// Person.m
#import "Person.h"
#interface Person()
#property (readwrite) NSString *lastName;
#end
#implementation Person
-(void)changeLastName:(NSString *)newLastName;
{
self.lastName = newLastName;
}
#end
Properties don't distinguish between callers when you're trying to set a property. If you want to set a readonly property from inside its class, use
_lastName = newLastName
in your case to set the ivar directly.
If you want to set a readonly property from inside its class, you can write the following code:
_lastName = newLastName
You need to redeclare it inside the class as readwrite
It's straightforward.
If you want to set a readonly property from inside its class, use
_lastName = newLastName
You need to redeclare it inside the class as readwrite

get Property attribute in continuation class does not match the primary class

In myClass.h, I do:
typedef enum {
SignUpLabel,
SignUpButton,
LogInFieldsTwitterButton,
LogInFieldsFacebookButton,
LogInWithFaceBookTiwtterLabel,
} logInFields;
#property (nonatomic, readonly, assign) logInFields fields;
#end
I want logInField to be readonly for public, but it can be read/write in private. Therefore, I do this:
#interface myClass ()
#property (readwrite, assign ) logInFields fields;
#end
However, I am getting a warning:
Property attribute in continuation class does not match the primary class
Can somebody tell me what I am missing here and how to silence the compiler?
Did you try adding "nonatomic" in the .m?

Difference between #property (nonatomic, readonly) and #property inside class extension?

I have an Objective-c class "MyClass". In MyClass.m I have a class extension that declares a CGFloat property:
#interface MyClass ()
#property (nonatomic) CGFloat myFloat;
#end
#implementation MyClass
#synthesize myFloat;
//...
#end
What changes (if anything) when the property is declared using the readonly keyword?
#interface MyClass ()
#property (nonatomic, readonly) CGFloat myFloat;
#end
#implementation MyClass
#synthesize myFloat;
//...
#end
Perhaps in the first case I can say self.myFloat = 123.0; and CGFloat f = self.myFloat; inside MyClass? Then in the second case the readonly keyword prevents the assignment self.myFloat = 123.0; but allows the read CGFloat f = self.myFloat;
The option readonly means that only the getter method is being declared for this property. Thus, without a setter, it can't be modified via myObject.myFloat=0.5f;
If you don't declare it readonly, it's read write by default.
Declaring your property via () extension does not modify the access mode but it modifies the scope; it will be a "private" property.
#synthesize uses the #property definition to generate the appropiate getter/setter for the iVar. When you specify readonly, no setter is generated. This is not strictly enforced as you can write your own setter if you choose (though that doesn't make a ton of sense).
Declaring the property in a category simply defines the scope of the property to be within that category.
You're right, declaring your property as readonly you tell compiler to not generate setter method automatically and so self.myFloat = 123.0; will be illegal (unless you create that method manually).