在 Objective-C 中隐藏 @property 时出现问题

发布于 2025-01-05 00:26:50 字数 708 浏览 0 评论 0原文

为什么在下面的示例中没有为 myString 合成 setter? 下面的基本赋值会导致 myStringnil。尝试使用 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 技术交流群。

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

发布评论

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

评论(3

我只土不豪 2025-01-12 00:26:50

其他两个答案是正确的,但我认为他们错过了你的意图。在 .h 文件中将属性声明为只读是很常见的,这样类实现之外的代码就无法写入它。在 .m 文件内,您希望它是可读写的。这种重新定义是明确支持的。但是,您需要将重新声明作为 readwrite 放入类扩展中:

// In your .h file:
@interface MyClass : NSObject
    @property (nonatomic, copy, readonly) NSString *myString;
@end

// In your .m file:
@interface MyClass () // Note the empty parentheses
    @property (nonatomic, copy, readwrite) NSString *myString;
@end

您仍然需要使用 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:

// In your .h file:
@interface MyClass : NSObject
    @property (nonatomic, copy, readonly) NSString *myString;
@end

// In your .m file:
@interface MyClass () // Note the empty parentheses
    @property (nonatomic, copy, readwrite) NSString *myString;
@end

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.

嘦怹 2025-01-12 00:26:50

看起来您正在尝试声明一个公开只读、私有可写的属性。您应该在类扩展而不是类别中执行此操作。从语法上讲,类扩展看起来像一个没有名称的类别:

@interface MyClass ()
@property (nonatomic, copy) NSString *myString;
@end

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:

@interface MyClass ()
@property (nonatomic, copy) NSString *myString;
@end
浮世清欢 2025-01-12 00:26:50

在 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.

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