这是在Objective-C中定义私有实例变量的新方法吗? [英] Is this a new way to define private instance variables in Objective-C?

查看:87
本文介绍了这是在Objective-C中定义私有实例变量的新方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近更新到Xcode 4.3.2,发现我现在可以在@implementation块中声明私有实例变量,如下所示:

I've recently updated to Xcode 4.3.2 and found that I can now declare private instance variables inside @implementation block like so:

@interface TestClass : NSObject
@property (nonatomic, copy) NSString *testProp;
@end

@implementation TestClass {
    NSString *_testPropStore;
}

- (NSString *)testProp { return _testPropStore; }
- (void)setTestProp:(NSString *)testProp { _testPropStore = [testProp copy]; }

- (id)init {
    if (self = [super init]) {
        _testPropStore = nil;
    }
    return self;
}

@end

注意@implementation大括号内的NSString *_testPropStore行.

我还用以下代码进行了测试:

I've also tested with the following code:

TestClass *c1 = [[TestClass alloc] init];
TestClass *c2 = [[TestClass alloc] init];

c1.testProp = @"Hello";
c2.testProp = @"World";

NSAssert(c1.testProp == c2.testProp, @"It's working!");

似乎工作正常. (也就是说,该应用程序崩溃并在NSAssert行显示正在运行"消息.)

Which seems to work fine. (That is, the app crashes with the "It's working" message at the NSAssert line.)

那么,这是Objective-C声明私有实例变量的新功能吗?由于我是偶然发现的,所以我很想知道这是否只是为了声明私有实例变量,还是会有我不知道的副作用?

我找不到任何相关文档,因为大多数带有private字样的此类问题最后都给出了如何在不同的私有扩展类别中声明它们的答案.

I couldn't find any relevant document since most questions of such type with the word private just ended up with answers on how to declare them on a private extension category which is different.

推荐答案

这是真实的,这是新方法,*很棒,是的,它在文档中. 目标-C编程语言与我们对这种语言的实际规范很接近,它具有以下含义:

It's for real, it's the new way,* it's great, and, yes, it's in the docs. The Objective-C Programming Language, which is as close as we get to having an actual spec for the language, has the following to say:

类的定义非常类似于其声明的结构.它以@implementation指令开头,以@end指令结束.另外,该类可以在@implementation指令之后的括号中声明实例变量:

The definition of a class is structured very much like its declaration. It begins with an @implementation directive and ends with the @end directive. In addition, the class may declare instance variables in braces after the @implementation directive:

@implementation ClassName
{
    // Instance variable declarations.
}
// Method definitions.
@end

从该链接可以追溯到一段历史记录,解决了我们以前不得不在接口块中声明ivars的事实:

There's also a historical note a little ways back from that link, addressing the fact that we used to have to declare ivars in the interface block:

从历史上看,该接口要求声明类的实例变量,即类的每个实例的一部分的数据结构. ...实例变量表示实现细节,通常不应在类本身之外访问.此外,您可以在实现块中声明它们,或使用声明的属性对其进行合成.因此,通常您不应在公共接口中声明实例变量,因此应省略花括号.

Historically, the interface required declarations of a class’s instance variables, the data structures that are part of each instance of the class. ... Instance variables represent an implementation detail, and should typically not be accessed outside of the class itself. Moreover, you can declare them in the implementation block or synthesize them using declared properties. Typically you should not, therefore, declare instance variables in the public interface and so you should omit the braces.

对于隐私问题,是的,这些变量确实是私有的-它们的行为就像在@private指令的接口中声明的ivars.这意味着默认情况下,子类无法访问它们.但是,可以使用@protected或(如果出于某些奇怪的原因而需要)@public:

For the question of privacy, yes, these variables are truly private -- they act like ivars declared in the interface with the @private directive. This means that subclasses can't access them, by default. Their visibility can be changed, however, using either @protected or (if necessary for some bizarre reason) @public:

@interface Stuper : NSObject 
@end

@implementation Stuper
{
    @protected
    NSString * sangfroid;
}
@end

@interface Stub : Stuper
- (void)setSangfroid: (NSString *)newSangfroid;
@end

@implementation Stub

- (void)setSangfroid: (NSString *)newSangfroid {
    sangfroid = [newSangfroid copy];
}


*我相信您必须使用clang> 3.0,所以距本文发布仅几个月前. GCC不会这样做.


*You have to use clang > 3.0, I believe, so that's just a few months ago as of this posting. GCC won't do it.

这篇关于这是在Objective-C中定义私有实例变量的新方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆