在 Objective-C 中隐藏 @property 时出现问题
为什么在下面的示例中没有为 myString
合成 setter? 下面的基本赋值会导致 myString
为 nil
。尝试使用 setter [self setMyString:s];
会导致无法识别的选择器异常。
// in .h file
@interface MyClass
@property (nonatomic, readonly) NSString *myString;
@end
// in .m file
@interface MyClass (MyCategory)
@property (nonatomic, copy) NSString *myString;
@end
@implementation MyClass
@synthensize myString;
- (void) someMethod:(NSString *) s {
myString = [s copy];
// why is myString nil here?
}
@end
编辑:问题出在 gdb 上。 po myString
打印无法打印 NIL 对象的描述。
。但是 NSLog(@"myString: %@", myString);
打印了预期值。
Why isn't a setter synthesized for myString
in the example below? The basic assignment below results in myString
being nil
. Trying to use the setter [self setMyString:s];
results in an unrecognized selector exception.
// in .h file
@interface MyClass
@property (nonatomic, readonly) NSString *myString;
@end
// in .m file
@interface MyClass (MyCategory)
@property (nonatomic, copy) NSString *myString;
@end
@implementation MyClass
@synthensize myString;
- (void) someMethod:(NSString *) s {
myString = [s copy];
// why is myString nil here?
}
@end
Edit: the problem was with gdb. po myString
printed Can't print description of a NIL object.
. However NSLog(@"myString: %@", myString);
printed the expected value.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
其他两个答案是正确的,但我认为他们错过了你的意图。在 .h 文件中将属性声明为只读是很常见的,这样类实现之外的代码就无法写入它。在 .m 文件内,您希望它是可读写的。这种重新定义是明确支持的。但是,您需要将重新声明作为 readwrite 放入类扩展中:
您仍然需要使用
self.myString = aString
或[self setMyString:aString]
来代替像您现在所做的那样直接写入 ivar 。The other two answers are correct, but I think they miss your intention. It's common to declare a property as read-only in the .h file, so that code outside the class implementation can't write it. Inside the .m file, you want it to be readwrite. This kind of redefinition is explicitly supported. However, you need to put the redeclaration as readwrite in a class-extension:
You do still need to use
self.myString = aString
or[self setMyString:aString]
, instead of writing to the ivar directly as you're doing right now.看起来您正在尝试声明一个公开只读、私有可写的属性。您应该在类扩展而不是类别中执行此操作。从语法上讲,类扩展看起来像一个没有名称的类别:
It looks like you're trying to declare a publicly readonly, privately writable property. You should do that in a class extension rather than a category. Syntactically, a class extension looks like a category with no name:
在 MyClass 接口和 MyCategory 类别中声明具有相同名称的属性似乎是一个坏主意。删除类别中的声明,我希望一切都会好起来。
Declaring a property with the same name in both your MyClass interface and your MyCategory category seems like a bad idea. Remove the declaration in the category and I expect all will be well.