目标C:我应该分配变量AND创建一个属性还是只是其中之一?

时间:2013-01-22 09:46:27

标签: objective-c variables properties header-files

我有一个头文件(.h),我想声明name,但所有这些方法都是一样的,我认为因为我没有看到任何功能上的差异。你能告诉我之间有什么区别:

这两个声明:

@interface someClass : UIViewController
{
    NSString *name;
}

@property (nonatomic, copy) NSString *name;

@end

没有变量:

@interface someClass : UIViewController
{

}

@property (nonatomic, copy) NSString *name;

@end

或没有财产:

@interface someClass : UIViewController
{
    NSString *name;
}

@end

2 个答案:

答案 0 :(得分:5)

   @interface someClass : UIViewController
   {
     NSString *name;
   }

   @property (nonatomic, copy) NSString *name;

   @end

执行此操作,您将明确声明属性和ivar。

属性只是一组方法:

 - (void)setName:(NSString*)name;
 - (NSString*)name;

ivar是保存属性方法管理的值的内存存储。这允许你这样做:

self.name = ... // access through setter method
name = ... // direct access

使用属性的优点是它们可以为您处理内存管理。例如,在您的情况下,属性的类型为copy:这意味着使用第一种语法(self.name = ...)将完成对象的副本。如果不使用属性,则明确需要执行:name = [originalString copy];以获得相同的效果。

您可以为属性(但不是ivars)指定的其他选项包括:strongweak所有权。

此外,属性还表示从类外部访问变量的公共接口。

使用直接访问,您可以自行管理内存(如果您不使用ARC)。 如果您使用ARC但未定义属性,则无法通过指定所有权来控制内存的管理方式:strong,weak,retain)。

 @interface someClass : UIViewController
 {

 }

 @property (nonatomic, copy) NSString *name;

 @end

这里你只声明属性; ivar由您的实现文件中的@synthesize指令“推断”。这只能在Objective C 2.0及更高版本中实现(之前,上述ivar声明是强制性的)。

与上述相同的考虑适用,具有细微差别:对于较旧版本的LLVM(ObjC编译器),您将无法直接引用自动合成的ivar;使用当前版本的LLVM,如果省略@synthesize指令,则还会声明以您的属性命名的自动ivar(在您的情况下,它将是_name)。

这最后一段可能看起来有点“先进”,或者做作,但你可以放心地忽略它。

 @interface someClass : UIViewController
 {
    NSString *name;
 }

 @end

在这种情况下,您只是声明了ivar。没有访问方法。您需要自己处理内存管理(如果不使用ARC),此外您将无法从课外访问变量。为此你需要访问者。

希望这有帮助。

答案 1 :(得分:1)

案例1:

这是旧方法,@property和变量在@synthesize name = name之前不相关;

访问方法: 变量:name = @"hello"; //direct access to viariable

setter / getter:self.name = @"hello" // set value to name using setName: selector

使用最新的xcode就足够了。

案例2: 新的xcode风格。这里编译器负责合成和变量创建。 (所以少了2行代码,这也有助于内存管理)

访问方法: 变量:_name = @"hello"; //direct access to viariable

setter / getter:self.name = @"hello" // set value to name using setName: selector

案例3: 这里的名称只是一个变量,它不具有setter或getter。 没有财产(或)setter& getter这和局部变量一样好,不能从其他对象访问。