目标C语言 为iOS 7设置变量值的最佳'init'方法?



我对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...方法(我们称之为"指定初始化器")。您可以简单地覆盖NSObjectinit方法。但是,如果需要,可以定义

- (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;
}

最新更新