我有一个头文件(.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
答案 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)指定的其他选项包括:strong
和weak
所有权。
此外,属性还表示从类外部访问变量的公共接口。
使用直接访问,您可以自行管理内存(如果您不使用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这和局部变量一样好,不能从其他对象访问。