我创建了单例类,并且有一个类对象(myRecords)作为其中的属性。我想在这个属性的getter / setter中做一些实现处理。
如何覆盖此属性的getter / setter?
注意:myRecord的初始化不是在单例内完成的。
// singleton.h
@interface mySingleton : NSObject
@property(nonatomic, copy) NSString *name;
@property(nonatomic) myRecords *record;
+(mySingleton *)instance;
@end
// singleton.m
@implementation TRNApplicationContext
+(mySingleton *)instance {
static mySingleton *_instance = nil;
@synchronized (self) {
if (_instance == nil) {
_instance = [[self alloc] init];
}
}
return _instance;
}
-(void) setRecord:(myRecords *)record
{
self.title = record.name;
. . .
}
-(myRecords *) record
{
return self.record; // Error - EXC_BAD_ACCESS
}
@end
// TestMainViewController.m - Below is Singleton usage
@implementation TestMainViewController
-(void)viewDidLoad
{
. . .
myRecords *someRecord = [myRecords new];
someRecord.name = @"test";
[[mySingleton instance] setRecord:someRecord];
NSLog(@"value : %@", [[[mySingleton instance] record] name]);
}
@end
答案 0 :(得分:5)
您有堆栈溢出错误。
您需要更改
-(myRecords *) record
{
return self.record; // call this method again and cause infinite recursion
}
到
@synthesize record = _record; // usually put this on the line below @implementation
-(myRecords *) record
{
return _record; // return the ivar
}
您还需要
_record = record;
在setRecord:
答案 1 :(得分:1)
你根本没有覆盖getter / setter。您正在提供自己的实现,而不是使用编译器提供的实现。你可以覆盖子类中的getter / setter,这将是一件非常非常奇怪的事情。
为了实现单身人士,我建议遵循涉及dispatch_once的常规模式。它效率更高,每个人都认可,每个人都知道它有效。
" myRecords"对于一个显然实现一条记录的类来说,它是一个非常非常奇怪的名称。对于阅读代码的人来说,这将是一个混乱的原因。类似的," mySingleton"对于一个班级来说,这个名字非常非常奇怪。当你需要一个不同的单身人士课时,你打算做什么,称之为myOtherSingleton?名称应该反映类的目的,而不是一些实现细节。
我强烈建议不要使用" new"方法但通常的模式[[myRecords alloc] init]。使用通用模式可以使代码更具可读性,并使代码更加自信。当我看到[someClass new]时,我知道我必须非常仔细地阅读周围的代码。
" setRecord" setter实际上并没有设置_records实例变量。 没有理由提供"记录"吸气。编译器提供的那个就可以了。正如其他人发布的那样,呼叫"记录"来自"记录" getter导致无限递归。
整个问题当然与单身人士无关。对于任何具有递归调用自身的getter的类,你都会遇到完全相同的崩溃。您还应该学习如何使用Xcode调试器。检测到崩溃时你应该做的第一件事是检查调用堆栈,你会发现getter调用了getter,getter调用了getter,getter调用了getter,永远如此。
答案 2 :(得分:0)
一种更简单的方法是减少代码,只需替换以下两种方法,因为已经在.h文件中声明了记录变量的属性。因此,只需在.m文件中声明相同变量的合成即可。
/* -(void) setRecord:(myRecords *)record
{
self.title = record.name;
. . .
}
-(myRecords *) record
{
return self.record; // Error -
EXC_BAD_ACCESS
}*/