Objective c 公共iVar;从其他类只读

Objective c 公共iVar;从其他类只读,objective-c,Objective C,使iVar可由其所属类写入,但只能由其他类读取的最佳方法是什么 有不止一种方法吗 我能想到的唯一方法是为iVar设置一个@property readonly,但不要在拥有的类中使用点符号,我猜这不适用于readonly,在拥有的类中直接引用它,不使用点符号,然后在另一个类中,使用点符号引用它 但我很好奇是否还有其他方法 您可以仅为实现而使属性读/写。您可以在实现中使用类扩展或匿名类别来实现这一点。更容易演示,例如,在.h中: @interface MyClass @property (read

使iVar可由其所属类写入,但只能由其他类读取的最佳方法是什么

有不止一种方法吗

我能想到的唯一方法是为iVar设置一个@property readonly,但不要在拥有的类中使用点符号,我猜这不适用于readonly,在拥有的类中直接引用它,不使用点符号,然后在另一个类中,使用点符号引用它


但我很好奇是否还有其他方法

您可以仅为实现而使属性读/写。您可以在实现中使用类扩展或匿名类别来实现这一点。更容易演示,例如,在.h中:

@interface MyClass

@property (readonly) NSInteger age;
...

@end
在你的.m中:

@interface MyClass () // class extension/anonymous category for private methods & properties
                      // implementation of these go in main @implementation

@property (readwrite) NSInteger age;
...

@end

@implementation MyClass

@synthesize age;
...

@end
现在,您可以在类内以读/写和从外部以只读方式使用该属性

对于私有方法也可以这样做

[注意:这是Objective-C,因此上面的内容不是防弹的-有一些方法可以调用properties setter-但是编译器将标记从类外部分配给属性的错误。]

评论后:


[注2:匿名类别/类扩展与命名类别非常相似。前者必须在主实现中实现,后者可以在@implementation classname categoryname或主实现中实现。此外,只有主接口、类扩展/匿名类别的接口以及主实现可以声明实例变量;命名类别的接口和实现可以不声明。属性可以在匿名类别和命名类别中声明,但是它们只能在主实现中合成,而不能在命名类别实现中合成。本说明在新闻发布时是正确的,其中一些功能We’随着Objective-C/Xcode的发展,您已经有所改变。]

您可以仅为实现而对属性进行读/写操作。您可以在实现中使用类扩展或匿名类别来完成此操作。例如,在.h:

@interface MyClass

@property (readonly) NSInteger age;
...

@end
在你的.m中:

@interface MyClass () // class extension/anonymous category for private methods & properties
                      // implementation of these go in main @implementation

@property (readwrite) NSInteger age;
...

@end

@implementation MyClass

@synthesize age;
...

@end
现在,您可以在类内以读/写和从外部以只读方式使用该属性

对于私有方法也可以这样做

[注意:这是Objective-C,因此上面的内容不是防弹的-有一些方法可以调用properties setter-但是编译器将标记从类外部分配给属性的错误。]

评论后:


[注2:匿名类别/类扩展与命名类别非常相似。前者必须在主实现中实现,后者可以在@implementation classname categoryname或主实现中实现。此外,只有主接口、类扩展/匿名类别的接口以及主实现可以声明实例变量;命名类别的接口和实现可以不声明。属性可以在匿名类别和命名类别中声明,但是它们只能在主实现中合成,而不能在命名类别实现中合成。本说明在新闻发布时是正确的,其中一些功能我们随着Objective-C/Xcode的发展而改变。]

使用ivar的专用说明符和类扩展来定义访问器-这样ivar对类是专用的

//FooClass.h @接口类:NSObject{ @私人int boo

} @结束

//FooClass.m

@接口类{

}

@属性非原子,赋值为int boo

@结束

@实现类

@合成boo; //


@end

使用ivar的专用说明符和类扩展来定义访问器-这样ivar对类是专用的

//FooClass.h @接口类:NSObject{ @私人int boo

} @结束

//FooClass.m

@接口类{

}

@属性非原子,赋值为int boo

@结束

@实现类

@合成boo; //


@结束

谢谢;两个后续问题:如果你命名类别,这有关系吗?我经常看到人们将私有声明放在私有声明中,另一个类如何访问属性的setter,即使公共属性是readwrite?我对他的原始帖子做了一些编辑,希望他会批准,但信息如下这是不正确的。这是一个类扩展而不是一个类别,有两个截然不同的东西。@andrewx-是的,如果你给类别命名,这是很重要的。命名的类别必须在@interface类类别名称中实现;而匿名类别又名扩展则在主@implementation类中实现。@andrewx-Objective-C是一个somewhat自由语言,部分原因是其动态特性。匿名类别/类扩展必须在@implementation classname主目录中实现;不能有@implementation classname。@implementation classname类别名称用于方法
s是命名类别的一部分,但事实上,您可以在@implementation classname主目录中,甚至在@implementation classname其他类别名称中,从命名类别实现一个方法-所有类别的方法只是成为类的一部分。@Lucas-是的,实例变量只能在@interface classname中声明,@interface classname和@implementation classname。属性看起来有点混乱,你可以在任何类别中声明它们,但是你只能在主实现中合成它们,但是你可以直接在类别中实现它们;接下来的两个问题:如果你命名类别有关系吗?我经常看到人们将Private作为Private声明,另一个类如何访问属性的setter,即使公共属性是readwrite?我对他的原始帖子做了一些编辑,希望他会批准,但目前的信息是不正确的。这是一个类扩展,而不是一个类别,有两个非常不同的地方。@andrewx-是的,如果你给类别命名,这很重要。命名类别必须在@interface类类别名称中实现;虽然匿名类别扩展是在主@implementation类中实现的。@andrewx-Objective-C是一种比较自由的语言,部分原因是它的动态特性。必须在主@implementation classname中实现匿名类别/类扩展;您不能有@implementation类名称。@implementation classname类别名称用于命名类别的方法,但事实上,您可以在主@implementation classname中的命名类别中实现方法,甚至在@implementation classname中实现其他一些类别名称-所有类别中的方法只是成为类的一部分。@Lucas-是,实例变量只能在@interface classname、@interface classname和@implementation classname中声明。属性看起来有点混乱,您可以在任何类别中声明它们,但只能在主实现中合成它们,但您可以直接在类别中实现它们。