从两天前开始学习objective-c的开发人员,我不明白以下两种方法之间的区别:
1.
@interface Person : NSObject @property NSString *firstName; @property NSString *lastName; @end
2.
@interface Person : NSObject{ NSString *firstName; NSString *lastName; } @end
使用Java语言,我们定义了两个字符串字段:
class Person extends Object{ (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;//In fact:private should be protected //setter and getter. //you can use ecplise tool to generate setter/getter method automaticly }
正如您可能想象的那样,必须为大量(1000或更多)复杂类编写这些方法最终会被证明是耗时的.Objective-C提供了合成的访问器方法,所以你应该使用@property和@synthesize指令.如果你编写代码如下:
@interface Person : NSObject NSString *firstName;//note that the default access level is 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;
请注意:理解点表示法的一个关键点是它仅适用于已声明合成访问器方法的实例变量.
实例变量的访问级别使用@protected,@ private和@public指令在类声明的@interface部分中指定.
@interface Person : NSObject @public NSString *firstName;//note that the default access level is protected. NSString *lastName; @end
从另一个类或方法或函数中的任何其他代码访问公共实例变量时,使用 - >指针运算符表示法.因此,您可以访问C++/C中的Public Filed,如:
[[Person alloc] init]->firstName = "your first name";
另一个问题是:
@interface Person : NSObject @property NSString *firstName; @property NSString *lastName; @end
相当于:
@interface Person : NSObject{ NSString *firstName; NSString *lastName; } @property NSString *firstName; @property NSString *lastName; @end
或不?并且ivar
相当于实例变量?
让我们开始吧 (2)
@interface Person : NSObject { NSString *firstName; NSString *lastName; } @end
在这种情况下firstName
,我lastName
知道ivars
或Instance Variables
对我来说,我一般不会申报ivars
.一些开发人员现在说你不应该把这些放在@interface
声明中有两个原因.
它向类的用户公开了有关实现的详细信息,这将导致其他开发人员使用或在某些情况下自己依赖应该可用的实现细节.
一些开发人员认为将这些放入
@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 { // 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; }
在将它与Java进行比较时,这与它相当接近
private String firstName; public void setFirstName(String aFirstName) { this.firstName = aFirstName; } public String getFirstName() { return this.firstName; }
我们创建实例变量的方式与我们实现的方式相同,就像它是正常的一样,ivar
但是没有什么可以说我在java中创建我的setter和getter所以我们必须自己做.请注意,ivar
java 中的这里仍然是私有的,它是我们向其他人开放的getter和setter.
还有一种你错过的第三种选择.由于在objective-c中的约定,@property
对于bool 会发生什么?
我们宣布它是这样的
@property (nonatomic) BOOL personForObject;
在目标c中,当涉及到bools时,吸气剂的名称略有不同.虽然我们对合成的二合一产品感到满意
- (void)setPersonForObject:(BOOL)aPersonForObject { self.personForObject = aPersonForObject; }
虽然使用吸气剂我们并不开心,但是当涉及到bools时,吸气剂应该从那开始,is
所以personForObject
吸气剂应该是,isPersonForObject
但是合成不知道这样,所以将自动生成吸气剂的另一种方式.所以我们需要在属性声明中告诉它
@property (nonatomic, getter=isPersonForObject) BOOL personForObject;
你现在必须亲自实现这个方法
- (BOOL)isPersonForObject { return self.personForObject; }
请注意,只有在您选择忽略我不推荐的约定时才需要这样做.
有问题请问.