替代app delegate中的全局变量 [英] Alternative to global variables in app delegate

查看:92
本文介绍了替代app delegate中的全局变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个带速度计的应用程序,如动画(仪表和箭头表示仪表上的某些东西)。我将箭头的位置存储在我的app delegate中声明的全局变量中。我这样做是因为箭头位置被更新并被几个类使用。

I am developing an application with a speedometer like animation (a meter and an arrow to indicate something on the meter). I store the arrow's position in a global variable declared in my app delegate. I am doing it this way because the arrow position is updated and used by several classes.

然而,我不安全这是一个好的还是坏的设计决定。我的想法是,因为它是一个非关键的信息(只是一个浮动),所以在全局存储时不会造成任何伤害。但每当我对自己说全球这个词时,我的OOP心就会受伤。

However, I am insecure whether this is a good or a bad design decision. My thoughts are that since it is a non-critical piece of information (just a float), no harm is done when storing it globally. But my OOP heart hurts every time I say the word "global" to myself.

或者我有单身人士,但据我所知,单身人士在使用时开发人员希望创建一个且只有一个特定对象的实例。

Alternatively I have studiet singletons, but as far as I have read, singletons are used when the developer wishes to create one and only one instance of a certain object.

我做得对还是有更合适的方式做我做的事?

Am I doing it correct or is there a more proper way of doing what I do?

推荐答案


我这样做是因为箭头位置被多个类更新并使用。

I am doing it this way because the arrow position is updated and used by several classes.

在很多情况下,你可以缩小范围。这减少了组件间依赖性。

in many cases, you can reduce the scope. this reduces inter-component dependency.


然而,我不安全这是一个好的还是坏的设计决定。我的想法是,因为它是一个非关键的信息(只是一个浮动),所以在全局存储时不会造成任何伤害。但每当我对自己说全球这个词时,我的OOP心就会受伤。

However, I am insecure whether this is a good or a bad design decision. My thoughts are that since it is a non-critical piece of information (just a float), no harm is done when storing it globally. But my OOP heart hurts every time I say the word "global" to myself.

也许你可以移动状态(浮动值) )你的车速表上的伊娃?例如:您可能只显示一个车速表视图:将它添加到视图模型中更有意义吗?或者也许是它的控制器? (是的,提供一个没有源代码的更具体的例子有点困难)

perhaps you can move the state (the float value) to an ivar in your speedometer? example: you likely display just one speedometer view: does it make more sense to add it to what is the view's model? or perhaps to its controller? (yes, it's a bit tough to provide a more specific example without the source)


或者我有学生单身,但就我而言已阅读,单身人士在开发人员希望创建一个且只有一个特定对象的实例时使用。

Alternatively I have studiet singletons, but as far as I have read, singletons are used when the developer wishes to create one and only one instance of a certain object.

不需要,以及维持严重的疼痛。我见过的大多数可可单身人士都不应该被认为是单身人士,并且引起了很多麻烦。更好的是,你可以编写使用零单例的程序。这是理想的,易于测试。因此,依赖于应用程序控制器的程序/类型已经受到可测试性和可重用性的影响。

not necessary, and a severe pain to maintain. most of the cocoa singletons i have seen should not have been considered singletons, and caused a lot of headaches. better yet, you can write programs which use zero singletons. this is ideal, and easy to test. as is, the programs/types which depend on the app controller's have been compromised wrt testability and reusability.


我做得对还是有更正确的方式来做我做的事情吗?

Am I doing it correct or is there a more proper way of doing what I do?

在绝大多数情况下,你可以简单地缩小范围并将其本地化,同时删除全球状态。稍微努力一点,你可以将这个值作为全局删除 - 这是最好的。

in the vast majority of cases, you can simply reduce the scope and localize it, while removing global state. with a little more effort, you can remove that value as a global -- that is best.

虽然这不是一件好事......让我们假设你真的真的真的非常必须引入全球状态:

although it is not a good thing... let's assume you really really really really really must introduce global state:


  • 使用单身人士。当你想重用它时,你会重写它很有可能。糖包衣什么是丑陋的。如果你的应用程序控制器由于太多的全局状态而变得一团糟,至少你有太多全局状态的事实将是显而易见的。

  • 在你的app控制器中保持你的全局状态。您的app控制器负责其初始化,生命周期和访问。

  • 将该状态提供给依赖项,因此它们不会返回(甚至知道)全局域(应用程序)控制器)。然后你可以减少影响。

  • don't use a singleton. chances are good that you will rewrite it when you want to reuse it. it sugar coats what is ugly. if your app controller is a mess due to too much global state, at least the fact that you have too much global state will be obvious.
  • hold your global state in your app controller. your app controller is responsible for its initialization, lifetime, and access.
  • provide that state to dependencies, so they do not refer back to (or even know about) the global domain (the app controller). then you may minimize the impact.

全局状态和应用程序/执行状态之间也存在明显差异。全球国家应该被淘汰。执行状态不是全局状态,而是本地化执行上下文。执行状态可以在适当的级别重新引入,更改,更新,测试和可预测的重用。一个好的设计将在需要时引入执行状态,并在适当的级别同时避免全局状态。

there's also a distinct difference between global state and application/execution state. global state should be eliminated. execution state is not global state, but localized execution context. execution state can be reintroduced at the right level, altered, and updated, tested, and reused predictably. a good design will introduce execution state when needed, and at the right level while avoiding global state.

更新

根据OP中的描述,您的样本与我想象的非常接近。它提供了一些额外的细节。所以下面的示例(你需要在明显的区域中添加一些内容以将它们拼凑在一起)演示了如何更新控制器接口,最后有两个免费的其他方法,进一步说明了如何使用它们: / p>

Your sample is pretty close to what i had imagined, based on the description in the OP. It provided some additional specifics. So the sample below (you'll need some additions in obvious areas to piece it all together) demonstrates how you could update the controller interfaces, and there are two free 'elsewhere' methods at the end which further illustrate how to use these:

@interface MONArrowPosition : NSObject
{
    float arrowPosition;
}

@end

@implementation MONArrowPosition

- (id)initWithPosition:(float)position
{
    self = [super init];
    if (nil != self) {
        arrowPosition = position;
    }
    return self;
}

@end

@interface MyViewController1 : UIViewController
{
    MONArrowPosition * arrowPosition; // << may actually be held by the model
}

@end

@implementation MyViewController1

- (void)applyRotation
{
    [self rotateLayer:arrow from:self.arrowPosition to:callStatus speed:METER_SPEED];
}

@end

@interface MyViewController2 : UIViewController
{
    MONArrowPosition * arrowPosition; // << may actually be held by the model
}

@end

@implementation MyViewController2

- (void)viewDidLoad
{
    [super viewDidLoad];
    /* ... */
    [self.slider addTarget:self action:@selector(sliderValueDidChange) forControlEvents:controlEvents];
}

- (void)sliderValueDidChange
{
    self.arrowPosition.arrowPosition = self.slider.value;
    [self arrowPositionDidChange];
}

@end

/* elsewhere: */
- (void)initializeArrowPosition
{
    /* The variable is set to a default of 0.0f */
    MONArrowPosition * arrowPosition = [[MONArrowPosition alloc] initWithPosition:0.0f];
    /* ... */
}

- (IBAction)someActionWhichPushesMyViewController1
{
    // depending on the flow of your app, the body of initializeArrowPosition
    // *could* be right here
    MyViewController1 * viewController = [[MyViewController1 alloc] initWithNibName:nibName bundle:bundle];
    viewController.arrowPosition = self.arrowPosition;
    /* push it */
}

然后如果MyViewController1推送MyViewController2 ,定位和设置箭头位置将很容易。视图控制器也可以在模型中共享一些信息。在您的示例中使用全局,您正在跨越许多实现,这会增加耦合,增加依赖性等。因此,如果您可以采用此方法并本地化执行状态,那么您将有一个良好的开端。那么你可以使用任意数量的MONArrowPositions视图控制器,它们不受全局状态的影响。再次,我不能使用提供的样本过于具体,但我认为这应该说明我最初概述的概念(我不认为需要进行项目范围的审查)。

and then if MyViewController1 pushes MyViewController2, locating and setting the arrow position will be easy. the view controllers may also be sharing some information in the models. with a global in your sample, you are crossing many implementations, which adds coupling, increases dependency, etc.. so if you can take this approach and localize the execution state, you're off to a good start. then you can use any number of view controllers with any number of MONArrowPositions, and they will not be subject to the effects of global state. again, i can't get too specific using the samples provided, but i think this should illustrate the concepts i originally outlined well enough (i don't think a project-wide review is needed).

这篇关于替代app delegate中的全局变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆