如何使方法仅对Obj-C中的属性可用?

时间:2012-08-12 13:39:07

标签: objective-c properties methods private

我还是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 就像方法中的代码是方法本身的本地代码一样

3 个答案:

答案 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方法确实非常有用。