Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to set value to readonly property using KVC in iOS?

I am trying to describe my confusion here. Let me know if this question need any modification.

Accordind to Apple documentaition: Reference for readonly property -

Apple documentation link

So we can't set value to readonly property because it's setter will not created. But I have created a demo project for testing this. I am sharing my code sample with you.

This is "ModelTest1.h" class. It has a readonly property.

#import <Foundation/Foundation.h>

@interface ModelTest1 : NSObject

@property (readonly) NSMutableArray  *arrTest;

@end

Now I am setting value in it using KVC. Because this property is readonly, so at runtime it should give me an error but it is not happening.

- (void)readonlyTest
{
    ModelTest1  *obj1 = [ModelTest1 new];

    NSLog(@"obj1.arrTest before = %@",obj1.arrTest);

    [obj1 setValue:[NSMutableArray new] forKey:@"arrTest"];

    NSLog(@"obj1.arrTest after = %@",obj1.arrTest);

    [obj1.arrTest addObject:@"Str 1"];

    NSLog(@"obj1.arrTest after 2 = %@",obj1.arrTest);

    [obj1 release];
}

Output is:

Console output

I am not getting one thing here that why memory is getting allocated in NSMutableArray even it is readonly. And why a string is adding into this readonly array.

I did this memory allocation test with NSString also using KVC and got same result. Value was set to readonly string using KVC.

This is my confusion regarding setValue for readonly property.

So am I misunderstood something about readonly property? or there is something else going on?

like image 711
Mohd Haider Avatar asked Nov 12 '15 17:11

Mohd Haider


1 Answers

The documentation you cite talks specifically about a setter method. That is not the same as KVC. KVC, by default, sets the underlying instance variable directly if it can't find a setter method to call. So, readonly suppresses synthesis of the setter method, but that doesn't stop KVC.

You can turn off this feature (KVC's ability to go straight to the instance variable) by setting a class's accessInstanceVariablesDirectly to NO, but the default is YES.

like image 128
matt Avatar answered Nov 20 '22 07:11

matt