Objective C 的实例变量,为什么要声明它们?
我很难理解为什么需要声明实例变量。让我解释一下我的意思..
例如..
@interface LearningViewController : UIViewController {
UILabel *myText; // <--- Instance Variables
}
@property (nonatomic,retain) IBOutlet UILabel *myText;
-(IBAction)method:(id)sender;
@end
这也可以像你所看到的那样完成
@interface LearningViewController : UIViewController {
//instance variables go here, but are not declared, I just leave this field blank
}
@property (nonatomic,retain) IBOutlet UILabel *myText;
-(IBAction)method:(id)sender;
@end
.. 在后一个示例中,我只为 UILabel *myText 构建了 setter / getter,
但在前一个示例中,我也声明了实例变量。
两者最终都会起作用,
@implementation LearningViewController
@synthesize myText;
-(IBAction)method:(id)sender {
[myText setText:@"hey"];
//or
NSString *myObject = [[NSString alloc]initWithString:@"hey"];
[myText setText:myObject];
}
现在两者都会产生相同的结果。所以我的问题是,为什么?这样做有什么好处? 时,为什么我要建造和反对呢?
NSString *myObject = [[NSString alloc]initWithString:@"hey"];
myText.text = myObject;
当我可以
[myText setText:@"hey"];
提前表示感谢
I'm having a hard time understanding why I need to declare Instance Variables. Let me explain what I mean..
for example..
@interface LearningViewController : UIViewController {
UILabel *myText; // <--- Instance Variables
}
@property (nonatomic,retain) IBOutlet UILabel *myText;
-(IBAction)method:(id)sender;
@end
this can also be done as
@interface LearningViewController : UIViewController {
//instance variables go here, but are not declared, I just leave this field blank
}
@property (nonatomic,retain) IBOutlet UILabel *myText;
-(IBAction)method:(id)sender;
@end
as you can see.. in the latter example I ONLY built the setter / getter for the UILabel *myText
but in the former I declared the Instance Variables too.
Both end up working in the end
@implementation LearningViewController
@synthesize myText;
-(IBAction)method:(id)sender {
[myText setText:@"hey"];
//or
NSString *myObject = [[NSString alloc]initWithString:@"hey"];
[myText setText:myObject];
}
now both things produce the same result. So my question is, why? and what are the benefits of doing them either way?
And why would I build and object
NSString *myObject = [[NSString alloc]initWithString:@"hey"];
myText.text = myObject;
when I can just do
[myText setText:@"hey"];
thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
此外,有时您希望在类中使用受保护或私有 iVar,而不是从中创建属性。 (例如,当您不想允许除此类(私有)或其后代(受保护)之外的任何对象访问 iVar 时。标头中声明的属性可用于任何可以“查看”该类的对象从信息隐藏的角度来看,自动将标头中的 ivars 声明为属性(带或不带花括号内的声明)可能不好。
您还可以向 .m 文件添加实现部分:您在其中声明的任何属性。将是私人的好处(显然)是在需要时实现信息隐藏,以及使用点表示法的能力。
Also, there are times when you want to use a protected or private iVar within a class and not make a property out of it. (for example, when you don't want to allow access of an iVar to anything but an instance of this class (private) or its descendants (protected). Properties declared in the header are available to any object that can "see" the target object. Automatically declaring ivars in the header as properties (with or without the declaration inside the curly braces) might be bad from the standpoint of information hiding.
You can also add an implementation section to your .m file: any properties you declare there will be private to the class. The benefit (obviously) is both in achieving information hiding where needed, and the ability to use the dot notation.
本来Objective-C是没有属性的,@synthesize也不存在。您必须声明您的 iVar(实例变量)并编写您自己的 setter 和 getter。
当语言和运行时被修改为包含属性和@synthesize时,事情变得更好了。您不再需要编写 setter 和 getter。但是您仍然必须申报您的 iVar。
后来,语言和运行时进一步发展,今天,您甚至不必声明您的 iVar。 (尽管我倾向于写 @synthesize example = _example; 这样我就可以控制生成的 iVar 的命名。)
这是一个新功能,仅受相对较新版本的运行时支持。不支持 4.x 以下的 iOS 版本,以及旧版本的 OSX。
如果您正在为今天和未来构建软件,请继续将它们保留下来,如果您需要遗留支持,请保留它们。
Originally Objective-C did not have properties and @ synthesize did not exist. You had to declare your iVar (instance Variable) and write your own setters and getters.
When the language and runtime were revised to include properties and @synthesize, things were nicer. You no longer had to write your setters and getters. However you still had to declare your iVar.
Later still, the language and runtime evolved more and today, you don't even have to declare your iVar. (Although I tend to write @synthesize example = _example; so I can control what the generated iVar is named.)
This is a new feature and is only supported by relatively recent versions of the runtime. iOS versions less that 4.x are not supported, as are older versions of OSX.
If you are building software for today and the future, Go ahead and leave them out, If yot need legacy support, leave them in.
在问题的第二部分,您只需使用点符号。您可以将
myText.text
设置为 @"hey",与第二个示例中的操作方式相同。是同义词
你不需要声明一个 NSString 来提前保存你的值。
On the second part of the question, you are simply using the dot notation. You can set your
myText.text
equal to @"hey", the same way you are doing it in the second example.is synonymous to
You don't need to declare an NSString to hold your value ahead of time.
您可以省略 iVar,但我不同意省略 iVar。 OOP 中的 .h 文件通常是显示所有变量和方法的头文件。它宣告了它们。假设将来你想看看这个类做了什么,你只需引用 .h 文件即可。或者假设其他人需要查看该类,或者使用该类与他的代码进行通信。它可以更轻松地查看变量,查看已声明的内容和未声明的内容。也就是说,如果您想专业编程。
现在这真的取决于你想做什么。您创建对象的原因是这样您可以稍后释放它。所以你继续使用它,当你用完你就用完了它。现在,当实例变量仅在一种方法中使用时,为整个类创建实例变量并不是一个好的设计决策。从某种意义上说,整个类都存储变量是很糟糕的,而实际上它只在一个方法中使用。在这种情况下,您应该只在该方法中创建该对象,并在完成后立即释放它。
现在有时做
[myText setText@"hello"];
有效。这实际上取决于您的代码。我想真正了解情况差异的唯一方法就是练习。有时你需要将标签设置到另一个对象中,从而创建一个对象。否则,它会自动释放等等......
无论如何,基本上,仅将实例变量用于将要全局使用的变量。当然还有 UI 元素(因为它们被整个类和界面构建器使用)。
希望这有帮助。
You can leave iVars out, however I do not agree leaving out the iVars. The .h file in OOP is typically a header file that displays all variables and methods. It declares them. Assuming in the future you want to see what this class does, you just refer to the .h file. Or assuming someone else needs to look at that class, or use that class with his code to communicate with it. It makes it easier to look at the variables, see what is declared and what is not. That is, if you want to be programming professionally.
Now it really depends on what you want to do. The reason you would create an object is that so you are able to release it at a later time. So you continue to use it, and when you are done you just finish using it. Now creating instance variables for the whole class when they are just used in one method is not a good design decision. It is poor in a sense that the whole class is storing the variable, when in fact it is only used in one method. In this case, you should only create that object in that very method, and release it as soon as you're done with it.
Now sometimes doing
[myText setText@"hello"];
works. It really depends on your code. I guess the only way to really know the difference in situations is practice. Sometimes you need to set the label into another object, thus creating an object. Otherwise, it gets autoreleased etc...
Anyway, basically, use instance variables only for variables that are going to be used globally. And UI elements of course (since they are used by the whole class and interface builder).
Hope this helps.
正如您的代码所示,从技术上讲,您不需要声明实例变量,大多数时候。
一个重要的例外是当您为旧版 (< 4.0) iOS 运行时以及可能使用 GCC 的 32 位 Mac OS X 运行时进行编译时,GCC 不支持实例变量的综合。
此外,如果您想为以后添加实例变量保留空间(如果您正在生成一个框架并希望稍后扩展一个类,则可能相关),您将需要显式声明实例变量。
编辑:长话短说:遗留问题、可移植性和可扩展性问题禁止显式 ivars。对于面向 10.6(尤其是 10.7)的应用程序,几乎不需要或不需要声明它们。
As your code demonstrates, you don't technically need to declare instance variables, most of the time.
One critical exception to this is when you are compiling for the old (< 4.0) iOS runtime, as well as possibly the 32-bit Mac OS X runtime using GCC, which does not support the synthesis of instance variables.
Additionally, if you want to reserve space for later addition of instance variables (can be relevant if you are producing a framework and expect to extend a class at a later point), you'll need to explicitly declare the instance variables.
Edit: Long story short: Legacy, portability and extensibility concerns proscribe explicit ivars. For applications targeting 10.6, and especially 10.7, there is little or no need to declare them.