我还是Objective-C的新手,我最近学会了如何创建属性,到目前为止一直很好,但有一件事困扰我的是,即使在制作属性之后,setter和getter方法仍然是公开可用的。
假设我有以下代码:
// myClass.h
@interface myClass : NSObject {
int _startPos;
}
@property (assign, readwrite, setter = setStartPos:, getter = getStartPos) int startPos;
-(void) setStartPos: (int) pos;
-(int) getStartPos;
@end
实现文件应该是不言自明的,我不是要做任何具体的事情。
现在,我在某处阅读,并在实践中尝试过如果你在实现文件中创建一个类别,并添加一些方法,那么就可以使这些方法不可见(又名 private < / em>)到myClass.m文件之外的东西。
“好吧”我想,并决定尝试一下:
//myClass.m
#import <Foundation/Foundation.h>
#import "myClass.h"
@interface myClass (hidden)
-(void) setHiddenStartPos: (int) hPos;
-(int) getHiddenStartPos;
@end
@implementation myClass (hidden)
-(void) setHiddenStartPos: (int) hPos {
_startPos = hPos;
}
-(int) getHiddenStartPos {
return _startPos;
}
@end
@implementation myClass
-(void) setStartPos: (int) Pos {
[self setHiddenStartPos: Pos];
}
-(int) getStartPos {
return [self getHiddenStartPos]; //this is to see if I can get the value from the hidden methods through the non-hidden ones
}
@end
一切都很好,并在 main()中进行测试我可以看到名字中带有“隐藏”的方法实际上是无法访问的,因此就好像它们是私有的一样。
然后我尝试将其添加到头文件中:
@property (assign, readwrite, setter = setHiddenStartPos:, getter = getHiddenStartPos) int
看看我是否可以通过属性访问隐藏的方法
但是当我这样做时,隐藏的方法变得可以在 main()中访问,并且整个计划只允许通过属性访问方法
所以我问你,有没有办法让方法对属性和/或对象本身无法访问?
编辑:我发现吸气剂通常不会出现在名称中,所以请停止评论吗?
还要强调我的意思: 我想在c#中创建属性,其中setter和getter的内容对属性本身是私有的
public int exampleProperty
{
set{...}
get{...}
}
它不使用方法作为getter和setter,因此setter和getter中的代码只能被属性访问, JUST 就像方法中的代码是方法本身的本地代码一样
答案 0 :(得分:4)
在.m文件中添加类继续。即:
@interface myClass ()
@property (assign, readwrite, setter = setHiddenStartPos:, getter = getHiddenStartPos) int hiddenStartPos;
@end
@implimentation myClass
@synthesize hiddenStartPos = _hiddenStartPos;
...
@end
查看:What is an Objective-C "class continuation"?
PS:你的吸气剂应该是hiddenStartPos
而不是getHiddenStartPos
......
答案 1 :(得分:2)
在我看来,你的困惑来自对@property声明究竟是什么的误解。它本质上是一个存在setter和getter方法的声明。
所以,这个
@property int hiddenStartPos;
与此相同
- (int)hiddenStartPos;
- (void)setHiddenStartPos;
因此,这两种方法的实现是属性的实现。通过对.h文件中的属性进行去除,您将向任何导入.h的人做广告,使得该类实现这两种方法(分别是getter和setter)。
我还想再次强调getter方法 在Objective-C中以“get”为前缀。
答案 2 :(得分:1)
你过分思考“私人”的含义。在ObjC中,“私人”只是意味着“不可见”。这并不意味着“不可赎回”。将方法设为私有的方法是不将它放在.h
文件中,该文件声明了您的公共接口。
无法控制谁传递消息。这是ObjC的一个关键事实,不能(也不应该)改变。 ObjC是一种动态语言。在运行时,我可以自由地生成选择器并在我想要的任何对象上调用performSelector:
。任何阻止这种情况的事情都会导致(a)引入重大的性能损失,或(b)在ObjC(可能两者)中打破许多非常有用和常用的技术。 ObjC不是Java或C#。它甚至不是C或C ++。这是在C之上的Smalltalk。它是一种高度动态的语言,具有很多优点。 Unlearning other languages是迈向成为优秀Cocoa开发人员的第一步。
对于方法(其属性只是一种特殊情况)进行编译器检查@private
会很好,并且对于方法进行编译器检查@protected
尤其令人敬畏(这些都适用于ivars)。这些会使稍微更简单,以避免某些错误。但这是你应该考虑这个问题的唯一方法。目标不是保护代码的一部分与代码的另一部分。其他代码不是敌人。这些都是由希望该程序工作的人编写的。目标是避免错误。正确的命名,一致性和绝对消除警告是你在ObjC中实现这一目标的方法。
所以是的,我很乐意偶尔将@protected
放在我的@property
声明面前。今天你不能,而且没有真正的等价物(我有时在一个单独的标题中使用+Protected
类别,但它通常比它的价值更麻烦)。但是那说,拥有它不会有太大变化,而且我只找到一个案例,我甚至每年都会使用它几次。我想不出单个案例,其中@private
方法确实非常有用。