在Objective-c中继承实例变量

时间:2022-09-07 07:38:07

In Objective-c 2.0 why do subclasses need to reference instance variables in parent classes using the self keyword?

在Objective-c 2.0中,为什么子类需要使用self关键字在父类中引用实例变量?

Consider this example:

考虑这个例子:

// a.h
@interface MyClass : NSObject
@property (nonatomic, retain) Object *myObject;
@end

// a.m
@implementation MyClass
@synthesize myObject;
@end


// b.h
@interface AnotherClass : MyClass
@end

// b.m
@implementation AnotherClass
- (void) someMethod {
    // error
    // Object *obj = myObject;

    // works
    // Object *obj = self.myObject;
}
@end

2 个解决方案

#1


11  

You haven't actually defined a variable, you only defined a property (which implicitly defines a variable that is private). And since property are just method, you need the dot syntax. Note that self.property is the same as [self property].

您实际上没有定义变量,您只定义了一个属性(隐式定义了一个私有变量)。因为属性只是方法,所以你需要点语法。请注意,self.property与[self property]相同。

To fix this, specify a variable. I'll give you an example where the variable has a different name than the property. Most people chose the same name for both but I like to have them differ so I immediately see which one is meant.

要解决此问题,请指定变量。我将举例说明变量的名称与属性不同。大多数人为两者选择相同的名称,但我喜欢让它们不同,所以我立即看到哪一个是意思。

// a.h
@interface MyClass : NSObject {
    // Instance variables are "protected" by default, except if you
    // use @private or @public.
    Object *myObjectVar;
}

@property (nonatomic, retain) Object *myObject;
@end

// a.m
@implementation MyClass
@synthesize myObject = myObjectVar;
@end


// b.h
@interface AnotherClass : MyClass
@end

// b.m
@implementation AnotherClass
- (void) someMethod {
    // works
    Object *obj = myObjectVar;

    // works
    obj = self.myObject;

    // the same as self.myObject
    obj = [self myObject];
}
@end

Note the difference when you assign: if you assign to your variable the object is not retained automatically. But it is retained if you use the property:

分配时注意差异:如果分配给变量,则不会自动保留对象。但如果您使用该属性,它将被保留:

myObjectVar = someObject; // not retained, old object not released!
self.myObject = someObject; // old object released, new object retained
[self setMyObject:someObject]; // same as the line above

Edit: Mentioned that the synthesized instance variables are private by default, as noted by @Jason Coco. And @NSGod is right that normal instance variables are protected by default rather than public, fixed that.

编辑:提到默认情况下合成的实例变量是私有的,如@Jason Coco所述。并且@NSGod是正确的,普通的实例变量默认是受保护的而不是公共的,固定的。

#2


8  

They don't, provided you actually declare an instance variable in the superclass, rather than rely on the new runtime's ability to synthesize the instance variable (in addition to synthesizing the accessor methods). See The Objective-C Programming Language: Runtime Difference for more info on instance variable synthesis.

如果您实际在超类中声明了一个实例变量,它们不会,而不是依赖新运行时合成实例变量的能力(除了合成访问器方法)。有关实例变量合成的更多信息,请参阅Objective-C编程语言:运行时差异。

For example, to be able to refer to the instance variable directly, you'd need to change the following:

例如,为了能够直接引用实例变量,您需要更改以下内容:

@interface MyClass : NSObject
@property (nonatomic, retain) Object *myObject;
@end

to:

至:

@interface MyClass : NSObject {
// there is an implied @protected directive here
    Object *myObject;
}

@property (nonatomic, retain) Object *myObject;

@end

By default, instance variables are @protected, meaning the class and any subclasses can access the instance variables directly. @protected ivars differ from @public ivars in that you can't access them using ->. @private ivars can only be accessed by the class that declares them. See The Objective-C Programming Language: The Scope of Instance Variables for more info.

默认情况下,实例变量是@protected,这意味着类和任何子类都可以直接访问实例变量。 @protected ivars与@public ivars的不同之处在于您无法使用 - >访问它们。 @private ivars只能由声明它们的类访问。有关详细信息,请参阅Objective-C编程语言:实例变量的范围。

#1


11  

You haven't actually defined a variable, you only defined a property (which implicitly defines a variable that is private). And since property are just method, you need the dot syntax. Note that self.property is the same as [self property].

您实际上没有定义变量,您只定义了一个属性(隐式定义了一个私有变量)。因为属性只是方法,所以你需要点语法。请注意,self.property与[self property]相同。

To fix this, specify a variable. I'll give you an example where the variable has a different name than the property. Most people chose the same name for both but I like to have them differ so I immediately see which one is meant.

要解决此问题,请指定变量。我将举例说明变量的名称与属性不同。大多数人为两者选择相同的名称,但我喜欢让它们不同,所以我立即看到哪一个是意思。

// a.h
@interface MyClass : NSObject {
    // Instance variables are "protected" by default, except if you
    // use @private or @public.
    Object *myObjectVar;
}

@property (nonatomic, retain) Object *myObject;
@end

// a.m
@implementation MyClass
@synthesize myObject = myObjectVar;
@end


// b.h
@interface AnotherClass : MyClass
@end

// b.m
@implementation AnotherClass
- (void) someMethod {
    // works
    Object *obj = myObjectVar;

    // works
    obj = self.myObject;

    // the same as self.myObject
    obj = [self myObject];
}
@end

Note the difference when you assign: if you assign to your variable the object is not retained automatically. But it is retained if you use the property:

分配时注意差异:如果分配给变量,则不会自动保留对象。但如果您使用该属性,它将被保留:

myObjectVar = someObject; // not retained, old object not released!
self.myObject = someObject; // old object released, new object retained
[self setMyObject:someObject]; // same as the line above

Edit: Mentioned that the synthesized instance variables are private by default, as noted by @Jason Coco. And @NSGod is right that normal instance variables are protected by default rather than public, fixed that.

编辑:提到默认情况下合成的实例变量是私有的,如@Jason Coco所述。并且@NSGod是正确的,普通的实例变量默认是受保护的而不是公共的,固定的。

#2


8  

They don't, provided you actually declare an instance variable in the superclass, rather than rely on the new runtime's ability to synthesize the instance variable (in addition to synthesizing the accessor methods). See The Objective-C Programming Language: Runtime Difference for more info on instance variable synthesis.

如果您实际在超类中声明了一个实例变量,它们不会,而不是依赖新运行时合成实例变量的能力(除了合成访问器方法)。有关实例变量合成的更多信息,请参阅Objective-C编程语言:运行时差异。

For example, to be able to refer to the instance variable directly, you'd need to change the following:

例如,为了能够直接引用实例变量,您需要更改以下内容:

@interface MyClass : NSObject
@property (nonatomic, retain) Object *myObject;
@end

to:

至:

@interface MyClass : NSObject {
// there is an implied @protected directive here
    Object *myObject;
}

@property (nonatomic, retain) Object *myObject;

@end

By default, instance variables are @protected, meaning the class and any subclasses can access the instance variables directly. @protected ivars differ from @public ivars in that you can't access them using ->. @private ivars can only be accessed by the class that declares them. See The Objective-C Programming Language: The Scope of Instance Variables for more info.

默认情况下,实例变量是@protected,这意味着类和任何子类都可以直接访问实例变量。 @protected ivars与@public ivars的不同之处在于您无法使用 - >访问它们。 @private ivars只能由声明它们的类访问。有关详细信息,请参阅Objective-C编程语言:实例变量的范围。