我对Objective C还是个新手,所以请原谅我:
我的app有一个委托,一个导航控制器和一个视图。对于"全局"变量,我也使用Singleton。
我知道我可以这样做,但是看起来很笨拙:
#import "GlobalData.h"
@synthesize ...
NSInteger junk;
NSInteger moreJunk;
-(void)myMethod{
GlobalData *globDat=[GlobalData getSingleton];
junk=globDat.someValue;
}
-(void)myOtherMethod{
GlobalData *globDat=[GlobalData getSingleton];
moreJunk=globDat.someOtherValue;
}
我想这样做,但它不能:
#import "GlobalData.h"
@synthesize ...
NSInteger junk;
NSInteger moreJunk;
GlobalData *globDat=[GlobalData getSingleton]; //Compiler won't allow this line
-(void)myMethod{
junk=globDat.someValue;
}
-(void)myOtherMethod{
moreJunk=globDat.someOtherValue;
}
但是我可以这样做:
#import "GlobalData.h"
@synthesize ...
NSInteger junk;
NSInteger moreJunk;
GlobalData *globDat;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
globDat=[GlobalData getSingleton];
}
return self;
}
-(void)myMethod{
junk=globDat.someValue;
}
-(void)myOtherMethod{
moreJunk=globDat.someOtherValue;
}
所以,是否有一个标准/通用/适当的"init"方法用于所有类?
我应该每节课都这么做吗?
-(id)init{
if(self=[super init]){
globDat=[GlobalData getSingleton];
}
return self;
}
我知道我可以这样做,但它看起来很笨拙…
您似乎在问如何取消从单例中检索所需值的部分。要做到这一点,最好的方法是从一开始就消除单例。
你说你有一个app委托,一个导航控制器和一个视图。你可能还有一个视图控制器。如果那些是应用程序中的主要对象,你可能会考虑将数据存储在视图控制器中。或者,将你的单例转换为合法的数据模型,并让你的视图控制器在属性中保留对它的引用。然后你可以这样说:
-(void)myMethod{
junk = self.model.someValue;
}
和你要求的很接近
这取决于您使用GlobalData
的程度。
在许多方法中广泛使用
如果您计划在您的类中(在许多方法中)广泛使用GlobalData
,那么,您最好添加@propertu (nonatomic, readwrite, weak)GlobalData *globalData
在你的.h
里(或者,在类扩展中更好)。在主init...
方法中,设置值self.globalData = [GlobalData getSingleton];
。您也可以这样做,在.h
或类扩展中使用实例变量GlobalData* myGlobalData
。
确保你的init...
方法以init
开始,并确保有一个"主"init...
方法(我们称之为"指定初始化器")。您可以简单地覆盖NSObject
的init
方法。但是,如果需要,可以定义
- (id)initWithString:(NSString*)str
{
self = [super init] ; // or another one ; here you should use the designated init. of the parent class
if (self){
self.string = str ;
self.globalData = [GlobalData getSingleton] ;
}
return self;
}
在少数方法中广泛使用
如果您在一个或两个方法中大量使用GlobalData
,则不需要这样做。您只需定义一个局部变量GlobalData * globalData = [GlobalData getSingleton];
并使用它。
您建议的第三个代码不是面向对象的。
我不是100%确定你的问题到底是什么(单例作为一种常见的模式vs常见的-init方法?),但是为你的类创建所谓的指定初始化器是很常见的。如果您没有使用单例模式,则接受值的init方法签名可能如下所示:
-(id)initWithValue:(NSString*)newValue;
至于使用单例模式来提供对变量的访问,我建议采用更松耦合的方法,特别是当单例类管理的值的数量开始增长时。我会将这些变量放入它们自己的类中(逻辑上分开),并根据需要使用它们,方法是将它们传递给构造函数或实例化它们。不过这是一个观点/哲学问题。
我最终用这个来解决这个问题。(同样,我主要是试图清除代码冗余)在我的Class模块中,我做了以下操作:
#import "GlobalData.h"
GloablData *globDat;
-(id)init{
if(self=[super init]){
globDat=[GlobalData getSingleton];
}
return self;
}
...
-(void)someMethod{
int junk=globDat.junkvalue;
}