这是我第一次尝试创建一个存储数据的对象,但遇到了一些麻烦。我不确定我是以正确的方式进行此事。
song.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
song.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
我的实现文件无法看到任何变量,例如我无法使用self.songID = p_songID
设置songID
objective-c是否有内置的处理这些setter / getter的方式,我是否采取了错误的方式?
答案 0 :(得分:7)
Objective C有一种为您设置getter和setter的方法,这样您就不必担心自己编写它们了。它通过属性来实现。要设置属性,请在头文件中写入
@property (strong, nonatomic) NSString *songID;
通常,您将使用强和非原子修饰符,除非您有理由不这样做。如果您有兴趣,可以研究其他参数。写完该行后,将为您生成getter和setter。
要在类中使用此属性,只需使用点表示法和自身对象。例如,要设置值,请编写
self.songID = @"66777888";
您以相同的方式访问属性的值。例如,要指定另一个等于该值的字符串,请编写
NSString *other = self.songID;
如果要在子类之外访问这些值,仍然使用点表示法,除非现在使用该类的实例。例如,如果要从另一个类设置songID,可以编写
Song *song = [[Song alloc] init];
song.songID = @"790";
答案 1 :(得分: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
是关于线程安全的。
答案 2 :(得分: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由编译器生成。 如果您不想为成员设置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'私有'。
答案 3 :(得分:0)
访问器方法的命名约定是getter与可能的属性同名,对于布尔属性,前缀为is
。它们不应以get
为前缀。 setter的前缀为set
,后跟大写属性名称。
所以,你可能有:
- (NSString*) title;
- (void) setTitle:(NSString*)newTitle;
等