2

我有一个别人写的项目,我已经接手了,希望能把这个应用做得更好。

我遇到了一个问题:

从一类:

我写_customclass.variable。CustomClass 是另一个类,变量是一个属性并且是 int 类型。我在这个类中获得了变量的值,但是当我将它更改为 self.customclass.variable 时,我总是得到 0。还有其他替代方法可以从其他类中获取值吗?

(一个)

@property (readwrite)int boxSpacing;

(二)

@synthesize boxSpacing;

(C)

- (id)initWithCoder:(NSCoder *)aDecoder {
    self.boxSpacing = 10;
}
4

2 回答 2

3

您问:

还有其他替代方法可以从其他类中获取价值吗?

简短的回答是,使用“getter”是从另一个类获取值的惯用方式。但是看看你的问题(承认,没有足够的源代码来正确诊断你的问题),我猜问题在于实例变量的使用。但稍后会详细介绍。

首先,让我们看看声明的属性及其实例变量及其访问器方法(getter 和 setter)的正确使用。通常,您应该使用这些访问器方法设置属性。但是,您可以使用实例变量从类中访问变量(并且您不应在初始化程序和 dealloc 方法中使用访问器方法)。并且在使用getter 和setter 时,您可以选择是使用方法调用(例如“ [self customObject]”)还是点表示法(例如“ self.customObject”)。

让我们看一个例子。假设您有一些简单的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

现在,让我们假设您CustomClass将从内部使用它,例如,您的视图控制器。所以,首先你声明 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

然后让我们演示如何在视图控制器中使用对象的value属性:CustomClasscustomObject

@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];
}

好的,让我们回到你的问题。你说:

我写_customclass.variable。CustomClass 是另一个类,变量是一个属性并且是 int 类型。我在这个类中获得了变量的值,但是当我将它更改为 self.customclass.variable 时,我总是得到 0。

好的,这可能是由几个不同的问题引起的,但我看到的最常见的问题是显式声明的实例变量和语句在幕后创建的实例变量之间的混淆@synthesize。这就是为什么我总是建议人们不要为他们声明的属性显式定义实例变量,而是让@synthesize语句自动执行此操作。这样我就不会遇到我要演示的那种问题。

考虑这个无害(虽然不正确)的例子:

@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);
}

你看到问题了吗?虽然我用下划线 . 声明了一个实例变量_customObject,但当编译器点击该@synthesize语句时,它创建了另一个实例变量,这次没有前导下划线customObject. 因此,我显式声明的实例变量从未收到 init/alloc,因此是nil,因此任何使用它的尝试都不起作用!

通常我们会看到相反的问题(一个显式声明的实例变量,没有下划线和@synthesize形式的声明@synthesize customObject = _customObject),但希望您能明白这一点。

无论如何,这是导致您描述的行为的最常见示例。如果这不是发生的情况,请为我们提供更广泛的代码示例。

但是,如果您遇到问题,我总是建议您CustomClass在尝试访问其属性之前检查对象本身的值。在尝试使用其属性之前,请确保已正确初始化类对象本身(无论是出于我上面列出的原因,还是其他一些初始化问题)。你可以做类似的事情NSLog(@"CustomClass object = %@", customObject);NSAssert(customObject, @"Object not properly initialized");

于 2012-09-25T21:02:32.513 回答
0

您是否为 CustomClass 定义了 @property?如果是这样,您是否分配了一个值?

如果不是,那么您将消息发送variablenil. 在你的情况下,这将导致 0。

于 2012-09-21T11:46:37.403 回答