简体   繁体   中英

Strange issue with readonly properties for iVars in iOS

Here is what I have:

@interface engine : NSObject
{

    int test;

}

@property (nonatomic, readonly) int test;

When I try to assign a value(10) to iVar test within my own class (engine class), the debugger shows test = 10, and _test = 0.

When I try to read from test, I get 0, I'm guessing i'm getting the value of_test.

How do I make it work the way it is supposed to? I want outside classes to have readonly access to "test", but within my class, I can assign and read values to/from "test"?

Or what is wrong with this implementation?

UPDATE:I do no syntesize as I use xcode 4.4 which automatially does it for you. I assume the synthesize will use the same iVar name as the property. Which is the default behaviour anyways if you do a normal synthesize.

Thanks.

It is hard to say without seeing your code, but I am guessing, that you are trying to do something like test=10 instead of self.test=10 . Depending on the version of ObjC/XCode you use and on a possible @synthesize statement, you are accessing a (whereever defined) local variable, but not the property resp. it's iVar.

EDIT

When you want to write a readonly property, you should use its iVar. Eg, after _test=10 both read accesses, self.test and _test (but not pure test !) should provide the same value.

You assume wrong. The default implementation is to produce the property name with an under bar. If you want a different name you will need to synthesize it yourself.

Automatic synthesize creates an instance variable with a underscore prefix, so a property called test generates a backing instance variable of _test . So you have two instance variables; test , which isn't connected to the property, and _test . If you write to the instance variable test , it will not be reflected in _test or the property's value.

But more to the point, declaring the backing instance variable yourself is pointless. It's just an extra code and unnecessary redundancy. The @property line already contains type, name, whether it's read/write or read-only and a storage qualifier. Just skip declaring the backing instance variable yourself and use the one the compiler generates for you.

In Engine.h:

@interface Engine : NSObject
@property (readonly, assign) NSInteger test;
- (void)doSomething;
@end

In Engine.m:

@implementation Engine

- (void)doSomething {
    _test++; // _test is created automatically by the compiler
}

@end

In other.m:

Engine *engine = [[Engine alloc] init];
NSLog(@"%d", engine.test); // 0
[engine doSomething];
NSLog(@"%d", engine.test); // 1

This all just works. Don't add to it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM