0

我还是 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

实现文件应该是不言自明的,我不想做任何具体的事情。
现在,我在某处读到,并在实践中尝试过,如果您在实现文件中创建一个类别,并向其中添加一些方法,则可以使这些方法对 myClass.m 文件之外的东西不可见(又名private )。

“好吧”我想,并决定尝试一下:

//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()中变得可访问,并且使方法只能通过属性访问的整个计划付诸东流

所以我问你,有没有办法让除了属性和/或对象本身之外的任何东西都无法访问方法?

编辑:我意识到 getter 通常没有 get 的名字,所以请停止评论它?

还要强调我的意思:我想在 c# 中创建属性,其中 setter 和 getter 的内容对属性本身是私有的

public int exampleProperty
{
    set{...}
    get{...}
}

它不使用方法作为 getter 和 setter,因此 setter 和 getter 中的代码只能由属性访问,就像方法中的代码是方法本身的本地代码一样

4

3 回答 3

4

在您的 .m 文件中添加一个类延续。IE:

@interface myClass ()
@property (assign, readwrite, setter = setHiddenStartPos:, getter = getHiddenStartPos) int hiddenStartPos;
@end

@implimentation myClass
@synthesize hiddenStartPos = _hiddenStartPos;
...
@end

看看:什么是Objective-C“类延续”?

PS:你的吸气剂应该只是hiddenStartPos而不是getHiddenStartPos......

于 2012-08-12T13:44:47.990 回答
2

在我看来,您的困惑来自于对 @property 声明的确切含义的误解。它本质上是声明存在 setter 和 getter 方法。

所以这

@property int hiddenStartPos;

和这个一样

- (int)hiddenStartPos;
- (void)setHiddenStartPos;

所以,这两个方法的实现就是属性的实现。通过 decar .h 文件中的属性,您向任何导入 .h 的人宣传该类实现了这两种方法(分别为 getter 和 setter)。

我还想再次强调,在 Objective-C 中,getter 方法不应“get”为前缀。

于 2012-08-12T14:52:21.430 回答
1

您过度思考“私人”的含义。在 ObjC 中,“private”只是意味着“不可见”。这并不意味着“不可调用”。将方法设为私有的方法是不要将其放入.h文件中,该文件声明了您的公共接口。

无法控制谁传递消息。这是 ObjC 的一个关键事实,不能(也不应该)改变。ObjC 是一种动态语言。在运行时,我可以自由地生成选择器并调用performSelector:我想要的任何对象。任何停止都会(a)引入显着的性能损失,或(b)破坏 ObjC 中许多非常有用和常见的技术(可能两者兼而有之)。ObjC 不是 Java 或 C#。它甚至不是 C 或 C++。它是基于 C 的 Smalltalk。它是一种高度动态的语言,并且有很多优点。学习其他语言是成为优秀 Cocoa 开发人员的第一步。

对方法进行编译器检查会很好@private(其中属性只是一种特殊情况),并且@protected对方法进行编译器检查会特别棒(这些存在于 ivars 中)。这些将使避免某些错误变得稍微简单一些。但这是你应该考虑的唯一方式。目标不是保护代码的一部分免受另一部分代码的影响。另一个代码不是敌人。这一切都是由希望程序运行的人编写的。目标是避免错误。正确的命名、一致性和绝对消除警告是您在 ObjC 中实现这一目标的方式。

所以是的,我希望能够偶尔@protected在我的声明前面。@property今天你不能,并且没有真正的等价物(我有时+Protected在单独的标题中使用一个类别,但它通常比它的价值更麻烦)。但话虽如此,拥有它不会有太大变化,我只发现我什至一年会使用几次的情况。不过,我想不出@private一种方法真正有用的情况。

于 2012-08-12T20:25:41.520 回答