I have a project which others have written and I have taken over it, hoping to make the app better.
I encountered one problem:
From one class:
I write _customclass.variable. CustomClass is another class and variable is a property and is of int type. And I get value of the variable in this class, but when I change it to self.customclass.variable, I always get 0. Is there other alternative ways to get value from other class?
(a)
@property (readwrite)int boxSpacing;
(b)
@synthesize boxSpacing;
(c)
- (id)initWithCoder:(NSCoder *)aDecoder {
self.boxSpacing = 10;
}
You asked:
Is there other alternative ways to get value from other class?
The short answer is that using the "getter" is the customary way to get a value from another class. But looking at your problem (admitted, not having enough source code to properly diagnose your issue), I'm guessing that the issue rests in the use of instance variables. But more on that later.
First, let's look at the proper use of declared properties and their instance variables and their accessor methods (the getters and setters). Generally you should set properties using these accessor methods. You can, though, use access a variable from within a class using either the instance variable (and you should not use accessor methods in initializer and dealloc methods). And when using the getter and setter, you can choose whether to use the method invocation (e.g. "[self customObject]
") or the dot notation (e.g. "self.customObject
").
Let's look at an example. Let's assume you have some simple CustomClass
:
@interface CustomClass : NSObject
{
// you don't need to declare the instance variable
//int _boxSpacing;
}
@property (nonatomic) int boxSpacing;
@end
@implementation CustomClass
// In Xcode 4.4 and later, the synthesize statement is optional, and if you
// omit it, it will synthesize the instance variable like this, with the
// leading underscore. While you don't need to use an underscore in your
// instance variable, it has become convention in iOS development and it's
// a good technique to minimize chances that you accidentally use the instance
// variable when you actual intended to use the property's accessor methods
// (the getter and setter).
@synthesize boxSpacing = _boxSpacing;
@end
Now, let's assume that you're going to use this CustomClass
from within, for example, your view controller. So, first you declare and instance of this CustomClass
:
@interface MyViewController : UIViewController
{
// you do not need this instance variable declaration
// the @synthesize statement will take care of this for you
// CustomClass *_customObject;
}
@property (nonatomic, strong) CustomClass *customObject;
@end
And then let's demonstrate how to use the value
property of the CustomClass
object customObject
from within your view controller:
@implementation MyViewController
// Again, in Xcode 4.4 and later, the synthesize statement is optional, and if you
// omit it, it will synthesize the instance variable like this, with the
// leading underscore
@synthesize customObject = _customObject;
- (void)customClassTest
{
// initialize the object
self.customObject = [[CustomClass alloc] init];
// set the property
self.customObject.boxSpacing = 1;
// finally, let's demonstrate three ways to retrieve the value
NSLog(@"%d", self.customObject.boxSpacing);
NSLog(@"%d", [[self customObject] boxSpacing]);
NSLog(@"%d", _customObject.boxSpacing);
// while we're at it, let's demonstrate other ways to set the property
_customObject.boxSpacing = 2;
// or
[[self customObject] setBoxSpacing:3];
}
Ok, so let's get back to your problem. You say:
I write _customclass.variable. CustomClass is another class and variable is a property and is of int type. And I get value of the variable in this class, but when I change it to self.customclass.variable, I always get 0.
Ok, this can be caused by a couple of different problems, but the most common problem I see is confusion between explicitly declared instance variables and the instance variables created behind the scenes by the @synthesize
statement. This is why I always advise that people not explicitly define the instance variables for their declared properties, but rather let the @synthesize
statement do that automatically. That way I can't have the sort of problem I'm about to demonstrate.
Consider this innocuous (though incorrect) example:
@interface MyViewController : UIViewController
{
CustomClass *_customObject;
}
@property (nonatomic, strong) CustomClass *customObject;
@end
@implementation MyViewController
@synthesize customObject;
- (void)customClassTestError
{
// initialize the object
self.customObject = [[CustomClass alloc] init];
// this works
self.customObject.boxSpacing = 1;
// this doesn't!
_customObject.boxSpacing = 2;
// when it hits this statement, the value will still be 1!!!
NSLog(@"%d", self.customObject.boxSpacing);
}
Do you see the problem? While I declared an instance variable with the underscore, _customObject
, when the compiler hit the @synthesize
statement, it created another instance variable, this time without the leading underscore, customObject
. Thus, my explicitly declared instance variable never received the init/alloc and therefore is nil
and thus any attempts to use it won't work!
Typically we see the converse problem (an explicitly declared instance variable without the underscore and a @synthesize
statement of the form @synthesize customObject = _customObject
), but hopefully you'll get the idea.
Anyway, this is the most common example of what would cause the behavior you describe. If this isn't what's going on, please provide us a more extensive code sample.
But if you're having problems, I'd always suggest that you check the value of your CustomClass
object, itself, before you try to access its properties. Make sure the class object itself has been properly initialized (whether for the reasons I list above, or some other initialization problem) before you try to use its properties. You can do something like NSLog(@"CustomClass object = %@", customObject);
or NSAssert(customObject, @"Object not properly initialized");
.
Have you defined a @property for the CustomClass? If so, have you assigned a value?
If not, then you're sending the message variable
to nil
. And in your case that will result to 0.
来源:https://stackoverflow.com/questions/12529833/ios-other-alternative-to-instance-variable