2

这是我第一次尝试创建一个对象来存储我的数据并且遇到了一些麻烦。我不确定我是否以正确的方式去做这件事。

歌曲.h:

#import <Foundation/Foundation.h>

@interface Song : NSObject{
    NSString *songID;
    NSString *title;
    NSString *artist;
    NSString *album;
    NSString *length;
    NSString *votes;
}
-(void)setSongID:(NSString*) p_songId;
-(void)settitle:(NSString*) p_title;
-(void)setartist:(NSString*)p_artist;
-(void)setalbum:(NSString*) p_album;
-(void)setlength:(NSString*) p_length;
-(void)setvotes:(NSString*) p_votes;

-(NSString*)getSongID;
-(NSString*)gettitle;
-(NSString*)getartist;
-(NSString*)getalbum;
-(NSString*)getlength;
-(NSString*)getvotes;

@end

歌曲.m

#import "Song.h"

@implementation Song


-(void)setSongID:(NSString*) p_songId;{

}
-(void)settitle:(NSString*) p_title{

}

-(void)setartist:(NSString*)p_artist{

}
-(void)setalbum:(NSString*) p_album{

}
-(void)setlength:(NSString*) p_length{

}
-(void)setvotes:(NSString*) p_votes{

}

-(NSString*)getSongID{

}
-(NSString*)gettitle{

}
-(NSString*)getartist{

}
-(NSString*)getalbum{

}
-(NSString*)getlength{

}
-(NSString*)getvotes{

}

@end

我的实现文件看不到任何变量,例如我无法设置 songIDself.songID = p_songID

Objective-c 是否有处理这些 setter/getter 的内置方式,我是不是走错了路?

4

4 回答 4

7

Objective C 有一种方法可以为您设置 getter 和 setter,这样您就不必担心自己编写它们。它通过属性来做到这一点。要设置属性,请在头文件中写入

@property (strong, nonatomic) NSString *songID;

通常,您将使用强和非原子修饰符,除非您有理由不这样做。如果您有兴趣,可以研究其他参数。写完该行之后,将为您生成 getter 和 setter。

要在类中使用此属性,您只需使用点表示法和 self 对象。例如,要设置值,您可以编写

self.songID = @"66777888";

您以相同的方式访问属性的值。例如,要分配另一个等于该值的字符串,您可以编写

NSString *other = self.songID; 

如果你想在子类之外访问这些值,你仍然使用点表示法,除了现在使用类的实例。例如,如果你想从另一个类设置 songID,你可以写

Song *song = [[Song alloc] init];
song.songID = @"790";
于 2013-08-26T00:32:09.027 回答
1

Objective-c 是否有处理这些 setter/getter 的内置方式,我是不是走错了路?

是的,Objective-C 有他自己的方式:@property.

您只想声明这样的属性:

@interface Song : NSObject
@property (strong, nonatomic) NSString * songID;
@end;

这将自动生成:

- (void)setSongID:(NSString *)songID;
- (NSString *)songID;

所以你不必自己写一个。

顺便说一句,strong意味着您想拥有该对象,它是您的。并且nonatomic是关于线程安全的。

于 2013-08-26T00:35:21.577 回答
1

您只需将您的课程编写为

@interface Song : NSObject

@property (strong, nonatomic) NSString *songID;
@property (strong, nonatomic) NSString *title;
@property (strong, nonatomic) NSString *artist;
@property (strong, nonatomic) NSString *album;
@property (strong, nonatomic) NSString *length;
@property (strong, nonatomic) NSString *votes;

@end

成员变量和 getter/setter 由编译器生成。如果您不想要成员的设置器,那么您将使用 readonly 说明符:

@property (strong, nonatomic, readonly) songID;

如果您需要特殊处理,您只需要手动提供 getter 或 setter 的实现。只是一个人为的例子:

@implementation Song

void setTitle:(NSString*)title
{
    if (some conditions)
        self.votes = @"winner";

    self.title = title;
}

@end

让编译器生成 getter 和 setter 不仅可以节省您无聊的打字时间并创建更简洁的代码,还可以处理同步和引用计数问题。但它并不适用于所有情况。如果生成原子属性和/或不使用 ARC,这些是需要担心的事情。

这里注意到编译器通过在属性前加下划线来为你生成成员变量。例如 _songID 或 _title 等。在类实现中,您可以访问和设置变量,例如

self.title = @"title";
_title = @"title";

哪一个合适?self.title - 在大多数情况下,_title - 在某些情况下。如果适用,请记住非 ARC 代码和原子实现。

如果您想让您的财产只能从您的班级(又名私人成员)访问,请使用班级扩展。在您的实现 .m 文件中:

@interface Song()
@property (strong, nonatomic) foo;
@end

@implementation Song
...
@end

为了完整起见,我要补充一点,您只能将 getter 或 setter 设为“私有”。

于 2013-08-26T00:36:17.357 回答
0

访问器方法的命名约定是 getter 可能与属性具有相同的名称,对于布尔属性,前缀为is. 它们不应以get. 并且 setter 以前缀set后跟大写的属性名称命名。

所以,你可能有:

- (NSString*) title;
- (void) setTitle:(NSString*)newTitle;

等等。

于 2013-08-26T00:31:37.003 回答