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

时间:2011-02-04 08:01:11

标签: objective-c subclass member

在将对象作为超类发送后,我无法访问子类的成员变量。会员职能正在发挥作用见这个例子:

超类定义

@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(nonatomic,assign)。调试器向我显示stringDerived的正确地址,但它“超出范围”。

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

谢谢,rodo

1 个答案:

答案 0 :(得分:1)

是:您违反了how to do properties的规则1。显然anotherString1在您从d.stringDerived读取的点之前被释放;在设置d.stringDerived时,它甚至可能无效。同样,anotherString显然是一个常量字符串或由其他东西保留。如果您展示了实际代码,那就更明显了。

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

完成此操作后,还必须确保在取消分配对象时正确计算属性值使用的内存。在dealloc例程中将任何对象类型属性的值设置为nil。