替代应用程序委托中的全局variables

我正在开发一个像animation一样的速度计(一个米和一个箭头来指示米上的东西)的应用程序。 我将箭头的位置存储在我的应用程序委托中声明的全局variables中。 我这样做是因为箭头位置被更新并被几个类使用。

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

或者,我有单子,但据我所知,当开发者希望创build一个特定对象的一个​​实例时,会使用单例。

我做的是对的还是有更正确的做法?

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

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

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

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

或者,我有单子,但据我所知,当开发者希望创build一个特定对象的一个​​实例时,会使用单例。

没有必要,还有一个很难维持的痛苦。 我所看到的大部分cocoa单体不应该被认为是单身人士,并且引起很多头痛。 更好的是,你可以编写使用零单例的程序。 这是理想的,而且容易testing。 因为依赖于应用程序控制器的程序/types已经被损害了可testing性和可重用性。

我做的是对的还是有更正确的做法?

在绝大多数情况下,您可以简单地缩小范围并将其本地化,同时消除全局状态。 多花点功夫,你可以把这个价值作为一个全球性的东西去除 – 这是最好的。

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

  • 不要使用单身人士。 当你想重复使用它时,你很可能会重写它。 它糖衣丑陋。 如果你的应用程序控制器由于太多的全局状态而变得混乱,至less全局状态太多的事实将是显而易见的。
  • 在你的应用控制器中保持你的全局状态。 您的应用程序控制器负责其初始化,生命周期和访问。
  • 提供该状态的依赖关系,所以他们不会引用(甚至不知道)全局域(应用程序控制器)。 那么你可以将影响降到最低。

全局状态和应用/执行状态之间也有明显的区别。 全球国家应该被淘汰。 执行状态不是全局状态,而是本地化的执行上下文。 执行状态可以在正确的级别重新引入,更改,更新,testing,并可预测地重用。 一个好的devise会在需要的时候引入执行状态,并且在避免全局状态的同时引入正确的级别。

更新

根据OP的描述,你的样本非常接近我所想象的。 它提供了一些额外的细节。 因此,下面的示例(您需要在明显的区域中添加一些附加内容以将它们组合在一起)演示了如何更新控制器接口,并在末尾有两个免费的“别处”方法,这些方法进一步说明如何使用这些方法:

@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,它们将不受全局状态的影响。 再次,我不能使用提供的样本太具体,但我认为这应该说明我原来概括的概念(我不认为需要进行项目范围的审查)。

那么这是在晚上保持了很多程序员的东西。

我尽量不要误用应用程序委托,我会创build一个单一的存储更多或更less的全局信息。 没有其他的方法可以做到这一点,无论是单身人士或应用程序的代表。

但是,如果只有一个viewController需要的信息比,信息将永远不会离开viewController。 该视图控制器可以将该信息传递给其他视图控制器是需要的。

在你的情况下,可能有一个想法,有一种方法pipe理器,其中包含浮动,甚至可能持有CLLocationManager。

对于这种types的事情,我喜欢使用NSNotifications。 所有关心箭头位置的视图控制器都会监听特定的通知,并且它们都可以一次更新UI。