在@Implementation下声明变量和.m文件下@Interface之间的区别 [英] Difference Between Declaring a Variable Under @Implementation And @Interface Under .m file

查看:108
本文介绍了在@Implementation下声明变量和.m文件下@Interface之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经学习Objective-C已有一段时间了.据我了解,我知道当您在 .h文件中的@interface中声明一个变量时,该变量可以被公共访问(类似于Java中的公共变量).

I have been learning Objective-C for awhile. From what I learned, I know that when you declare a variable inside @interface in the .h file, the variable can be accessed publicly(similar as a public variable in java).

@interface MyObject

@property NSInteger intData;

@end

但是当您在 .m文件@interface内部声明它时.只能在.m文件中的@implementation下对其进行访问,除非您为其提供了一个getter和setter方法.

But when you declare it inside @interface in the .m file. It can only be accessed inside the .m file under @implementation only, unless you provide a getter and setter for it.

@interface MyObject ()

@property NSInteger intData;

@end

但是我还注意到了另一种声明变量的方法,即在@implementation

But I also noticed another way of declaring a variable, which is declaring it under @implementation

@implementation

NSInteger intData;

@end

,我发现它的工作方式与在.m文件中的@interface@property下声明它的方式相同

and I see that it works the same way as declaring it under @interface with @property in .m file

我不明白两者之间的区别(在@implementation和@interface(在 .m文件中声明)).

I don't understand the difference between the two(declaring under @implementation and under @interface(in .m file).

我已经在堆栈中进行了搜索,但是他们都在谈论@implementation和@interface(在 .h文件中)之间的区别.因此,认为这不是重复项.

I've already searched through stack about this, but they were all talking about the difference between @implementation and @interface(in .h file). So think this is not a duplicate.

推荐答案

首先,您不是在声明变量.您是在声明财产.属性由实例变量支持,但它还会添加方法.这是放置变量的地方的说明:

First off, you're not declaring a variable; you're declaring a property. A property is backed by an instance-variable, but it also adds methods. Here's an explanation of the places to put variables:

@interface MyClass : NSObject {
    NSInteger i ;
}
@end

这是在您的类上放置实例变量的地方.它只能通过您的类和类别的方法来访问. (旁注:可以从外部访问它,但这不是推荐的做法)

This is a place to put an instance variable on your class. It is only accessible by methods of your class and categories. (Sidenote: it CAN be made accessible externally, but that's not a recommended practice)

另一个例子:

@interface MyClass : NSObject
@end

@implementation MyClass {
    NSInteger i ;
}
@end

这也是一个实例变量,但只能由该块内部编写的方法进行访问. (旁注:可以通过深入研究类定义来访问它,但这不是推荐的(或常见的)做法)

This is also an instance variable, but is only accessibly by methods written inside that block. (Sidenote: it can be accessed by digging through the class definition, but that's not a recommended (or common) practice)

另一个例子:

@interface MyClass : NSObject
@property NSInteger i ;
@end

与以下相同:

@interface MyClass : NSObject {
    NSInteger _i ; // you are not allowed to access it by this variable
}
- (NSInteger) i ;
- (void) setI:(NSInteger)value ;
@end

这是允许人们获得和设置的财产.您可以在您的方法或其他方法中以如下方式使用该变量:

This is a property people are allowed to get and set. You use that variable in your methods or in other methods as:

NSLog ( @"The value is %i" , self.i ) ; // if it's your instance method
NSLog ( @"The value is %i" , object.i ) ; // if it's object's instance method

另一个例子:

@interface MyClass : NSObject {
    NSInteger i ;
}
@property NSInteger i ;
@end
@implementation MyClass
@synthesize i ; // Causes the property to line up with the ivar by the same name.
@end

与以下相同:

@interface MyClass : NSObject {
    NSInteger i ; // you ARE allowed to use this since you defined it
}
- (NSInteger) i ;
- (void) setI:(NSInteger)value ;
@end

在这里,您可以使用getter/setter方法或实例变量本身.但是,通常应该使用这些方法,因为[隐式]声明了它们为原子的,因此它们具有线程同步.如果要使其不执行线程化(并加快速度,只要您不打算在多线程环境中使用它):

Here, you can use the getter/setter methods or the instance variable itself. However, you should generally use the methods because you [implicitly] declared them atomic so they have threading synchronization. If you want to make it NOT do threading (and speed it up, as long as you're not going to use it in a multi-threaded environment):

@property (nonatomic) NSInteger i ;
@property (nonatomic,readonly) NSInteger i ; // only makes a getter method

我建议暂时避免这种情况,并使用Straight属性,因为它可以帮助您避免许多常见错误.除非您对程序进行概要分析并确定这是导致性能下降的原因,否则您可能应该只使用这些属性.

另一个例子:

@interface MyClass : NSObject
@end

@implementation MyClass
NSInteger i ;
@end

这是一个实例变量.这是一个全局变量,恰好是在您的@implementation范围内编写的.

This is NOT an instance variable. It is a global variable that happens to have been written inside your @implementation scope.

有关如何将其转换为实例变量(即,将其放在大括号中)的信息,请参见上文.

See above for how to turn this into an instance variable (i.e. putting it in braces).

另外一个注意事项:

声明这样的属性:

@interface MyClass ()
@property NSInteger i ;
@end

不将其设为私有.但是,它隐藏在人们通常无法访问的文件中,因此编译器不知道存在属性.

Doesn't make it private. However, it is hidden in a file that people generally can't access so the compiler doesn't know a property exists.

您代码中其他地方的其他函数仍可以调用:

Other functions elsewhere in your code CAN still call:

[yourObject i] ;

要获取该属性的值-但他们必须首先知道它的存在.

To get the value of that property - but they have to know it's there first.

在评论中回答问题的附录:

Addendum to answer a question in the comments:

默认情况下,属性是原子的.它不一定遵循原子的严格定义(这是一罐蠕虫,我建议您现在不要看),但具有相同的效果:保证线程可以完整地看到. -to-date值,而不管何时另一个线程写入该值.通常在合成getter/setter方法时会这样做:

Properties are, by default, atomic. It doesn't necessarily follow the strict definition of atomic (this is a can of worms I suggest you not look at right now), but has the same effect: threads are guaranteed to see a complete and up-to-date value, regardless of when another thread writes to it. It generally does this when it synthesizes the getter/setter methods:

- (NSInteger) i {
    @synchronized(self) {
        return i ;
    }
}
- (void) setI:(NSInteger)value {
    @synchronized(self) {
        i = value ;
    }
}

如果您改为指定nonatomic,它将合成以下内容:

If you instead specify nonatomic, it'll synthesize these:

- (NSInteger) i {
    return i ;
}
- (void) setI:(NSInteger)value {
    i = value ;
}

如果您的媒体资源是atomic,则永远不要直接访问ivar.这样做违反了您最初给它的线程保护. (旁注:在某些情况下可以,但是请等到对线程/同步更加熟悉之后再尝试.)

If your property is atomic, then you shouldn't ever access the ivar directly. Doing so violates the threading protection you gave it to begin with. (Sidenote: there are cases where you can, but wait until you become more familiar with threading/synchronization before you attempt it.)

这篇关于在@Implementation下声明变量和.m文件下@Interface之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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