ericn
ericn

Reputation: 13103

How to get and set private instance variable/ property from outside a class Objective C?

I have a class MyConfig with a property/ variable NSString * url. By private, I don't want anyone to be able to set the url outside of the MyConfig class. For example, I don't want the following to be allowed:

MyConfig * myConfig = [[MyConfig alloc] init];
myConfig.url = @"some url";// I want to forbid this

My goals:

What I have: MyConfig.h

@interface MyConfig : NSObject
@property (readonly) NSString * url;
@end

Problem: standard getter is not working!

MyConfig * myConfig = [[MyConfig alloc] init];
[myConfig setUrl];// Instance method "-setUrl:" not found (return default type is "id")

This shouldn't be the case according to this right?

Is there a better way to achieve my goal?

Upvotes: 2

Views: 175

Answers (2)

Popeye
Popeye

Reputation: 12093

You could try creating a public property for your getter such as you have already and then create the private version in your implementation file such as below.

MyConfig.h

// Public interface that the world can see
@interface MyConfig : NSObject

@property (readonly) NSString *url; // Readonly so the getter will be generated but not the setter

@end

MyConfig.m

#import "MyConfig.h"

// Private interface that only your implementation can see
@interface MyConfig() // Class extension
@property (nonatomic, strong) NSString *url; // Private getter and setter
@end

@implentation MyConfig

// The rest of your code...  

@end

The way that I have implemented this is using class extensions, the syntax to declare a class extension is the same as the one for creating a category with an empty name. Moreover and quite an important part is that we don't have to define another implementation block, the implementation for this extension and the code in it has to be implemented in the main implementation block.

Using the class extension method (Not possible with categories) we can have a property with a readonly access public facing and readwrite access privately. To do this we declare the property as readonly in your header file and redeclare it as readwrite in your class extension.

Upvotes: 2

Khaled Barazi
Khaled Barazi

Reputation: 8741

The easiest way is to declare this property in your implementation (.m) file:

@interface MyConfig () //This declares a category/extension to your header file
@property (nonatomic, strong) NSString * url; //This property is private
@end

@implementation MyConfig
//Your code
@end

Upvotes: 1

Related Questions