在将对象作为超类发送后,我无法访问子类的成员变量。会员职能正在发挥作用见这个例子:
超类定义
@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
答案 0 :(得分:1)
是:您违反了how to do properties的规则1。显然anotherString1
在您从d.stringDerived读取的点之前被释放;在设置d.stringDerived时,它甚至可能无效。同样,anotherString
显然是一个常量字符串或由其他东西保留。如果您展示了实际代码,那就更明显了。
如果您定义具有对象类型属性的类,则必须安排类的实例复制或保留分配给该属性的值,以确保在您下次查看时它仍然存在。如果使用assign,则该值可能会很快变为无效,因为它可能是自动释放的值。通常,如果属性类型符合NSCopying协议并且它是可变的或具有可变子类(例如:NSString,NSData,NSSet,NSArray等),则最好使用copy以使值不会更改一次组;在其他情况下,使用保留是好的。
完成此操作后,还必须确保在取消分配对象时正确计算属性值使用的内存。在dealloc例程中将任何对象类型属性的值设置为nil。