作为超类发送后无法访问子类的成员

发布于 2024-10-15 20:36:08 字数 1196 浏览 6 评论 0原文

将对象作为超类发送后,我无法访问子类的成员变量。会员功能正在发挥作用。请参阅此示例:

超类定义

@interface SuperClass : NSObject {
 NSString *stringSuper;
 NSInteger intSuper;
}
- (void)test; // NSLog(@"test: SuperClass");

派生类定义

@interface DerivedClass : SuperClass {
 NSString *stringDerived;
 NSInteger intDerived;
}
- (void)test; // NSLog(@"test: DerivedClass");
- (void)test1; // NSLog(@"test1: DerivedClass");

创建一个 DerivedClass 对象并作为 SuperClass 发送

DerivedClass *d = [[DerivedClass alloc] init];
d.stringSuper = anotherString;
d.intSuper = anotherInt;
d.stringDerived = anotherString1;
d.intDerived = anotherInt1;

[anObject sendMessage:d];

尝试在强制转换为 DerivedClass 后访问成员

- (void)sendMessage:(SuperClass *)s {
 DerivedClass *d = (DerivedClass *)s;
 NSLog(@"%@", d.stringSuper); // ok
 NSLog(@"%d", d.intSuper); // ok
 NSLog(@"%@", d.stringDerived); // EXC_BAD_ACCESS
 NSLog(@"%d", d.intDerived); // ok

 [d test]; // ok ("test DerivedClass")
 [d test1]; // ok ("test1 DerivedClass")
}

我已为所有成员声明了 @properties(非原子,分配)。调试器向我显示了 stringDerived 的正确地址,但它“超出范围”。

有谁知道这种行为的原因是什么?

谢谢,罗多

I can't access member variables of a sub class after sending object as super class. Member functions are working. See this example:

super class definition

@interface SuperClass : NSObject {
 NSString *stringSuper;
 NSInteger intSuper;
}
- (void)test; // NSLog(@"test: SuperClass");

derived class definition

@interface DerivedClass : SuperClass {
 NSString *stringDerived;
 NSInteger intDerived;
}
- (void)test; // NSLog(@"test: DerivedClass");
- (void)test1; // NSLog(@"test1: DerivedClass");

create a DerivedClass object and send as SuperClass

DerivedClass *d = [[DerivedClass alloc] init];
d.stringSuper = anotherString;
d.intSuper = anotherInt;
d.stringDerived = anotherString1;
d.intDerived = anotherInt1;

[anObject sendMessage:d];

try to access members after cast to DerivedClass

- (void)sendMessage:(SuperClass *)s {
 DerivedClass *d = (DerivedClass *)s;
 NSLog(@"%@", d.stringSuper); // ok
 NSLog(@"%d", d.intSuper); // ok
 NSLog(@"%@", d.stringDerived); // EXC_BAD_ACCESS
 NSLog(@"%d", d.intDerived); // ok

 [d test]; // ok ("test DerivedClass")
 [d test1]; // ok ("test1 DerivedClass")
}

I've declared @properties (nonatomic, assign) for all members. The debugger shows me the correct address for stringDerived, but it is "out of scope".

Does anybody know what is the reason for this behavior?

Thanks, rodo

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

愁杀 2024-10-22 20:36:08

是的:您违反了如何处理属性的规则 1 。显然 anotherString1 在您从 d.stringDerived 读取的点之前被释放;它甚至可能在您设置 d.stringDerived 时无效。同样,anotherString 显然要么是常量字符串,要么被其他东西保留。如果您展示了实际的代码,情况会更明显。

如果您定义具有对象类型属性的类,则必须安排类的实例复制或保留分配给该属性的值,以确保您下次查看时它仍然存在。如果您使用分配,该值可能会很快变得无效,因为它可能是自动释放的值。一般来说,如果属性类型符合 NSCopying 协议,并且它是可变的或者有可变的子类(例如:NSString、NSData、NSSet、NSArray 等),那么最好使用 copy,这样值一次就不会改变放;在其他情况下,使用retain就可以了。

完成此操作后,您还必须确保在释放对象时正确考虑属性值使用的内存。在 dealloc 例程中将任何对象类型属性的值设置为 nil。

Yes: you have violated rule 1 of how to do properties. Clearly anotherString1 was released before the point you read from d.stringDerived; it may even have been invalid at the point you set d.stringDerived. Equally, anotherString is obviously either a constant string or retained by something else. It would have been more obvious if you had shown your actual code.

If you define a class with an object-type property you must arrange for instances of your class to copy or retain the value assigned to that property in order to be assured that it will still be there when you next look. If you use assign the value will probably become invalid very quickly as it is likely to be an autoreleased value. In general, if the property type conforms to the NSCopying protocol and it is mutable or has a mutable subclass (for example: NSString, NSData, NSSet, NSArray, etc) it is best to use copy so that the value doesn't change once set; in other cases it is fine to use retain.

Having done this you must also ensure that the memory used by the property value is correctly accounted-for when the object is deallocated. Set the value of any object-type properties to nil in your dealloc routine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文