Abdul Samad
Abdul Samad

Reputation: 5918

Objective C Semi Readonly property

I want to declare a public NSString property in my class which acts as a readonly property outside my class but i can assign any value to it inside my class. How can i achieve this behavior.

Upvotes: 1

Views: 1127

Answers (7)

zaph
zaph

Reputation: 112857

Define the property as readonly in the header and declare it readWrite in the implementation file in a class extension. The property will be readonly outside the classs implementation and read/write in the implementation.

// Interface file:
@interface Test : NSObject
@property (nonatomic, copy, readonly) NSString *propertyString;
@end

// Implementation file:
@interface Test () // Class Extension
@property (nonatomic, copy, readwrite) NSString *propertyString;
@end

@implementation Test
@end

See: Use Class Extensions to Hide Private Information

As @Amin Negm-Awad points out in an answer: the interface and class extension do not need to be in an interface or implementation file albeit this is the usual usage.

Upvotes: 3

Goppinath
Goppinath

Reputation: 10739

You have to declare your property in the .h file like this

@interface MyClass : NSObject

@property (strong, nonatomic, readonly) NSString *aString;

@end

but in your .m file you have to have

@interface MyClass () // your anonymous category

@property (strong, nonatomic, readwrite) NSString *aString;

@end

@implementation MyClass

@end

Externally the aString is readonly and internally you can set the value (readwrite).

You are achieving it by implementing a anonymous category also known as class extension in Objective-C

Upvotes: 5

Mike
Mike

Reputation: 9835

Define the property as readonly in the header, and set it using the underscore syntax.

@property (nonatomic, readonly) NSString *myString;

- (void)someMethodInYourDotMFile {
    _myString = YES;
}

Upvotes: -1

Amin Negm-Awad
Amin Negm-Awad

Reputation: 16650

Beside the existing answers that told you to define a readonly property and change it to a readwrite property, which is completely correct and the intended pattern (that is, what readwrite is for), I want to add an probably important information:

You put the readonly definition in the interface. (Not header!)

You put the readwrite definition in a class continuation. (Not implementation file)

One might say that this is the same, because interfaces reside in the header and class continuations reside in the implementation file. But this is only the usual case.

You can additionally put class continuations in a third file. Then something like a "friend class" can import it additionally and this "fried class" has write access. I do that very often, when developing frameworks.

MyClass.h: // public header, available for everybody

@interface MyClass : NSObject
@property (readonly, …) id property1; // Everyone can read it
@property (readonly, …) id property2; // Everyone can read it
- (void)method; // Everyone can use it
@end

MyClass_Package.h: // project header, available for framework classes, unavailable for the user of the framework

@interface MyClass()
@property (readwrite, …) id property1; // All classes inside the framework can write it
- (void)packageMethod;                 // All classes inside the framework can use it
@end

MyClass.m

@interface MyClass() // A second class extension inside .m
@property (readwrite, …) id property2; // Only MyClass can write it
- (void)privateMethod;                 // Only MyClass can use it
@end

Upvotes: -1

Injectios
Injectios

Reputation: 2797

This might be quit obvious:

in your .h file declare property as readonly

@property (nonatomic, assign, readonly, getter = isLoading) BOOL loading;

in your .m file declare property as readwrite

@property (nonatomic, assign, readwrite, getter = isLoading) BOOL loading;

This is an example, obviously you should create strong NSString property, and I assume compiler won't allow to set other value outside the class, but inside it will.

Upvotes: 0

bogdan
bogdan

Reputation: 61

In .h file add:

@property(nonatomic,readonly)NSString* property;

In .m file add:

@interface yourClass ()

@property(nonatomic,readwrite)NSString* property;

@end

Upvotes: 1

gnasher729
gnasher729

Reputation: 52530

Define the property as readonly in your header file (interface), and as readwrite in your implementation file. That also allows you easily to make it weak / strong / copy.

Upvotes: 0

Related Questions