Objective-c和Java之间的字段,我不明白@property和实例变量 [英] The Field between Objective-c and Java, and I don't understand the @property and instance variable

查看:128
本文介绍了Objective-c和Java之间的字段,我不明白@property和实例变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从两天前开始学习objective-c的开发人员,我不明白以下两种方法的区别:



1。

  @interface Person:NSObject 

@property NSString * firstName;
@property NSString * lastName;

@end

2。

  @interface Person:NSObject {

NSString * firstName;
NSString * lastName;
}

@end

使用Java语言定义两个字符串字段:

 类Person扩展对象{
(public / private / protected)String firstName;
(public / private / protected)String lastName;
}



我想知道哪一个(1和2之间)上面的Java代码。






非常感谢@iamyogish @ Popeye,如果我的答案是正确的,我会纠正你。
阅读电子书:Objective-C 2.0 Essentials后,我学到了(如果不对,你告诉我。):

  @interface Person:NSObject 

@property NSString * firstName;
@property NSString * lastName;

@end

这相当于Java代码:

  class Person extends Object {
private String firstName;
private String lastName; //其实:private应该被保护
// setter和getter。
//你可以使用ecplise工具自动生成setter / getter方法
}

你可以想象,不得不为大数(1000或更多)的复杂类编写这些方法将最终证明是耗时的。 Objective-C提供合成的访问器方法,所以你应该是使用@property和@synthesize指令。如果你编写你的代码,如下:

 code> @interface Person:NSObject 

NSString * firstName; //注意默认访问级别是protected。
NSString * lastName;

@end

不幸的是,您需要提供可以访问实例变量,如(你可以自己定义函数的名称)

   - (NSString)getFirstName; 
- (NSString)getLastName;
- (void)setFirstName:(NSString * name);
- (void)setLastName:(NSString * name);

除此之外,如果使用@property和@synthesize指令,像C ++ / JAVA语法点符号:

  NSString * firstName = [[Person alloc] init] .firstName; 

注意:关于点符号的关键点是它只适用于实例变量



实例变量的访问级别在类声明的@interface部分中使用@protected,@private和@public指令指定。

  @interface Person:NSObject 
@public
NSString * firstName; //注意默认访问级别受到保护。
NSString * lastName;

@end

当从另一个类或任何在方法或函数中的其他代码,使用 - >指针运算符符号。所以你可以访问C ++ / C中的Public Filed:

  [[Person alloc] init]  - > firstName =你的名字;另一个问题是:

 >  @interface Person:NSObject 

@property NSString * firstName;
@property NSString * lastName;

@end

等效于:

  @interface Person:NSObject {
NSString * firstName;
NSString * lastName;
}

@property NSString * firstName;
@properties NSString * lastName;

@end

ivar 等效于实例变量吗?

解决方案

(2)

  @interface Person:NSObject 
{
NSString * firstName;
NSString * lastName;
}
@end

在这种情况下 firstName 或 实例变量 code>对我来说,我通常不会声明 ivars 。一些开发人员现在说,你不应该把这些放在 @interface 声明中有两个原因。



  1. 它向类的用户公开了实现的细节,这将导致其他开发人员使用和在某些情况下自己依赖于应该可用的实现细节


  2. 一些开发人员认为将这些放在 @interface 中可以使编译时间显着更长。



大多数开发人员认为实现 ivar @implementation 中使用大括号:

  @implementation Person {
NSString * firstName;
NSString * lastName;
}

为什么我们把它们放在这里的原理是因为理论上他们被声明为私有的,阻止任何人知道他们,除了创建类的开发人员。这将解决所有其他开发人员搞乱他们不应该的东西。



在Java中相当于 private String firstName;






现在让我们看看(1)

  @interface Person:NSObject 

@property NSString * firstName;
@property NSString * lastName;

@end

技术上 @properties 只需要使用属性需要从其他类访问时,但许多开发人员更喜欢使用这些 ivars ,因为它使它们更容易使用,在 xcode 的新版本中,这些属性的 ivars 会在后台自动声明。



通过声明属性,您基本上会自动生成 getters setters 这些属性。在 xcode 的早期版本中,您必须 @synthesize ,但是不再需要了。因此,声明两个属性 firstName lastName 这将在后台生成

   - (void)setFirstName:(NSString *)aFirstName 
{
self.firstName = aFirstName;
}

- (NSString *)firstName
{
//注意在objective-c中我们一般不使用`get`
return self 。名字;
}

- (void)setLastName:(NSString *)aLastName
{
self.lastName = aLastName;
}

- (NSString *)lastName
{
//注意在objective-c中我们一般不使用`get`
return self 。姓;
}



当与Java比较时, / p>

  private String firstName; 

public void setFirstName(String aFirstName){
this.firstName = aFirstName;
}

public String getFirstName(){
return this.firstName;
}

我们创建实例变量的方式与我们做一个正常的 ivar 但没有什么可说的创建我的setters和getters在java所以我们必须这样做自己。注意,在java中的 ivar 这里仍然是私有的,是我们向其他人开放的getters和setter。



< hr>

有一个第三个选项,你也错过了。由于目标c的约定,对于bool, @property 会发生什么?



声明为

  @property(nonatomic)BOOL personForObject; 

在目标c中的bool getter的名称稍有不同。虽然我们对

   - (void)setPersonForObject:(BOOL)aPersonForObject 
{
self.personForObject = aPersonForObject;
}



我们不高兴,虽然与getter,当谈到bools getter应该以开头,因此 personForObject s getter应该是 isPersonForObject 但是synthesize不知道这样会自动生成getter的另一种方式。所以我们需要在属性声明中告诉它

  @property(nonatomic,getter = isPersonForObject)BOOL personForObject; 

现在您必须自己实现此方法,例如

   - (BOOL)isPersonForObject 
{
return self.personForObject;
}

注意,只有当你选择忽略约定时,



任何问题,只要问。


From the developer that started to learn objective-c two days ago, I don't understand the difference between the following two methods :

1.

 @interface Person : NSObject

   @property NSString *firstName;
   @property NSString *lastName;

 @end

2.

  @interface Person : NSObject{

    NSString *firstName;
    NSString *lastName;
  }

 @end

Using Java-Language,we define two String Field:

class Person extends Object{
  (public/private/protected) String firstName;
  (public/private/protected) String lastName;
}

I want to know which one(between 1 and 2) has same meaning with the Java code above.


Very thanks for @iamyogish @Popeye,if my answer is right i will correct both of you. After read the eBook: Objective-C 2.0 Essentials,I learned that(if it is not right,you tell me. ):

@interface Person : NSObject

   @property NSString *firstName;
   @property NSString *lastName;

 @end

this is equivalent to the Java Code:

class Person extends Object{
 private  String firstName;
 private String lastName;//In fact:private should be protected
 //setter and getter.
 //you can use ecplise tool to generate setter/getter method automaticly
}

As you can probably imagine, having to write these methods for large numbers(1000 or more.)of complex classes will ultimately prove to be time consuming. Objective-C provides synthesized accessor methods,so what you should is use of the @property and @synthesize directives.if you write your code like this:

@interface Person : NSObject

    NSString *firstName;//note that the default access level is protected.
    NSString *lastName;

 @end

Unfortunatly, you need to provide methods that can access instance variables,such as(you can define the name of the function by yourself)

-(NSString ) getFirstName;
-(NSString ) getLastName;
-(void) setFirstName:(NSString * name);
-(void) setLastName:(NSString * name);

In addition to this,if the @property and @synthesize directives are used,you can access instance variables like C++/JAVA syntax dot notationsuch as:

 NSString * firstName= [[Person alloc] init].firstName;

Note that: A key point to understand about dot notation is that it only works for instance variables for which synthesized accessor methods have been declared.

The access level for instance variables is specified in the @interface section of the class declaration using the @protected, @private and @public directives.

 @interface Person : NSObject
 @public
    NSString *firstName;//note that the default access level is protected.
    NSString *lastName;

 @end

When accessing a public instance variable from another class or any other code in a methods or function, the -> pointer operator notation is used. So you can access the Public Filed in C++/C like:

  [[Person alloc] init]->firstName = "your first name";

Another question is:

  @interface Person : NSObject

   @property NSString *firstName;
   @property NSString *lastName;

 @end

is is equivalent to:

@interface Person : NSObject{
   NSString *firstName;
   NSString *lastName;
 }

   @property NSString *firstName;
   @property NSString *lastName;

 @end

or not? and ivar is equivalent to instance variable or not?

解决方案

Lets start with (2)

 @interface Person : NSObject
 {
 NSString *firstName;
 NSString *lastName;
 }
 @end

In this case firstName and lastName are know as ivars or Instance Variables for me I don't generally declare ivars. Some developers now say that you shouldn't put these in the @interface declaration for two reason.

  1. It exposes details about the implementation to users of the class, this will lead other developers who or using and in some cases yourself to rely on implementation details that should be available to them.

  2. Some developers believe that putting these in the @interface can make compile times significantly longer.

Most developers believe that the best way to implement an ivar is within the @implementation where braces are being used like:

@implementation Person {
    NSString *firstName;
    NSString *lastName;
}

The theory behind why we put them here is because theoretically they are declared private, preventing anyone from knowing about them except the developer who created the class. This will resolve all other developers from messing around with things they shouldn't.

The equivalent to this in Java is just as simple as private String firstName;


Now lets take a look at (1)

@interface Person : NSObject

@property NSString *firstName;
@property NSString *lastName;

@end

Technically @properties need only be used when the property needs to be accessible from other classes, but many developers prefer to use these over ivars as it makes them easier to use, and in new versions of xcode the ivars for these properties are declared automatically in the background.

By declaring a property you are basically automatically generating the getters and setters for these properties. In earlier versions of xcode you did have to @synthesize but there is no need for this anymore. So declaring the two properties firstName and lastName this will generate in the background

- (void)setFirstName:(NSString *)aFirstName
{
    self.firstName = aFirstName;
}

- (NSString *)firstName
{ 
    // Note in objective-c we don't generally use `get`
    return self.firstName;
}

- (void)setLastName:(NSString *)aLastName
{
    self.lastName= aLastName;
}

- (NSString *)lastName
{ 
    // Note in objective-c we don't generally use `get`
    return self.lastName;
}

When it comes to comparing this to Java this is near enough the same as

private String firstName;

public void setFirstName(String aFirstName) {
    this.firstName = aFirstName;
}

public String getFirstName() {
    return this.firstName;
}

We create out instance variable the same way we would do it as if it was a normal ivar but there is nothing to say create my setters and getters in java so we have to do that ourselves. Note that the ivar here in java is still private it is the getters and setters that we are opening up to others.


There is a sort of third option that you have missed as well. Due to the conventions in objective-c what would happen with a @property for a bool?

We have it declared like

 @property (nonatomic) BOOL personForObject; 

in objective-c when it comes to bools the getter is slightly different in name. Whilst we are happy with the synthesized setter of

- (void)setPersonForObject:(BOOL)aPersonForObject 
{
    self.personForObject = aPersonForObject;
}

we aren't happy though with the getter, when it comes to bools the getters should start with is so personForObjects getter should be isPersonForObject but the synthesize doesn't know this so will automatically generate the getter the other way. So we need to tell it in the property declaration like

@property (nonatomic, getter=isPersonForObject) BOOL personForObject;

You will now have to implement this method yourself though like

- (BOOL)isPersonForObject
{
    return self.personForObject;
}

Note this only need be done if you choice to ignore convention which I wouldn't recommend.

Any questions just ask.

这篇关于Objective-c和Java之间的字段,我不明白@property和实例变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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