2

我是 iOS 开发的新手,在理解某些情况下有困难。我的问题是我是否同时需要变量和属性?

例如我看到这样的代码:

#import <Cocoa/Cocoa.h>

@interface Photo : NSObject {
    NSString* caption;
    NSString* photographer;
}
@property (retain) NSString* caption;
@property (retain) NSString* photographer;

@end

但是,据我所知,如果我删除变量标题摄影师代码仍然可以工作:

#import <Cocoa/Cocoa.h>

@interface Photo : NSObject

@property (retain) NSString* caption;
@property (retain) NSString* photographer;

@end

所以,请解释使用第一个和第二个的区别。

谢谢,任何建议!

4

3 回答 3

2

{} 括号内的变量是实例变量。只有班级可以访问它们。

@property 定义了一些由 (options) 表示的不同事物。

大多数人使用 @property 来方便 .m 和 .h 文件中的方法。例如

@property (strong) NSString *string;

在您的 .h 和 .m 文件中创建两个对您不可见的方法,称为:

-(NSString *)string; //returns the string object
-(void)setString:(NSString *)string;

所以它所做的是提高可读性并帮助减少大量样板代码。

现在不再需要在 {} 括号内定义实例变量。

如果您需要将实例变量设置为不同的名称,您可以放置​​一个

@synthesize string = _string;

既然你是新来的,我会添加一些额外的东西供你考虑。self.string = @"string" 可能不是与 string = @"string" 等效的调用

如果你有 @property (strong) NSString *string; 和@synthesize 字符串;这样做的原因是通过 self.string 设置字符串是使用方法实现来设置字符串,并且可以像这样被覆盖:

-(void)setString:(NSString *)str{
    string = [NSString stringWithFormat:@"%@.jpg", str];
}

所以 self.string = @"hello" 将是 @"hello.jpg" 其中 string = @"hello" 只是 "hello"

还有 self.string = @"string"; 与 [self setString:@"string"] 很相似;

为了澄清 @property(strong)NSString *string 在 .h 中的作用,添加:

{
   NSString *_string;
}
-(void)setString:(NSString *)string;
-(NSString *)string;

内部.m:

-(void)setString:(NSString *)string{
_string = string;
}

-(NSString *)string{
return _string;
}

因此,除非您想将 iVar 重命名为其他名称,否则无需调用 @synthesize @synthesize string = wibblyWobblyTimeyWimey;

所以在.h中它会是

{
NSString *wibblyWobblyTimeyWimey;
}

在.m里面

-(void)setString:(NSString *)string{
wibblyWobblyTimeyWimey = string;
}

-(NSString *)string {
return wibblyWobblyTimeyWimey;
}
于 2013-09-01T12:18:41.277 回答
1

如果您使用的是 Xcode 4.6.x,并且您已使用 Clang 4 或更高版本安装了命令行工具,则可以利用“自动合成”属性。

@interface Photo : NSObject

@property (retain) NSString* caption;
@property (retain) NSString* photographer;

@end

将为您提供实例变量 _caption 和 _photographer。所以不,在大多数情况下你真的不需要声明实例变量。如果您使用的是 ARC,那么只有使用属性才有意义。

如果您使用 ARC,该代码应如下所示:

@interface Photo : NSObject

@property (strong) NSString* caption;
@property (strong) NSString* photographer;

@end

此外,通常最好指定nonatomic属性。不这样做将意味着 clang 将生成的访问器将使用锁:

@interface Photo : NSObject

@property (strong, nonatomic) NSString* caption;
@property (strong, nonatomic) NSString* photographer;

@end
于 2013-09-01T12:04:06.513 回答
0

你不可以。中的变量{}是私有成员,继承此头文件的类无法访问,而properties可以通过继承类访问、读取和写入。

但情况并非总是如此。在某些情况下,(如delegates),两者都是必需的。

于 2013-09-01T12:00:47.793 回答