0

可能重复:
我的 Objective-C 单例应该是什么样的?

我试图了解单例的使用。我有红色要小心他们,而且他们可以有他们的积极用途。

我的场景:

目前我已经建立了一个测试项目。一个 ViewController 有一个需要执行操作的按钮。

FirstViewController 上有一个 UIWebView 。

我正在使用 Storyboard 和 ContainerView,所以我可以同时看到两个 ViewController。

在第一个 ViewController 中,我的 .m 文件中有以下代码:

static FirstViewController *sharedController = nil;

+ (FirstViewController *)sharedController {

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    //BBCSermonTabBarViewController *myVC = (BBCSermonTabBarViewController *)[storyboard instantiateViewControllerWithIdentifier:@"BBCNews"];

    if(sharedController == nil)
        sharedController = (FirstViewController *)[storyboard instantiateViewControllerWithIdentifier:@"firstViewController"];

    return sharedController;
}

而且我还有一种方法可以像这样更改 alpha:

-(void)hideWebView
{
    _webView.alpha = 0.3;
}

现在在我的第二视图控制器中,我有以下代码:

-(IBAction)hideWebViewFromAnotherViewController
 {
   [[FirstViewController sharedController] hideWebView];
 }

该操作按钮现在应该更改另一个 ViewController 中 webView 的 alpha 吗?

如果不是我做错了什么?

提前致谢:-)

4

3 回答 3

1

为了安全起见,并且因为使用 libdispatch 非常简单,您应该使用 dispatch_once() 调用来保护单例创建者,而不是执行 if() 检查。

+ (FirstViewController *)sharedController {

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];

    static dispatch_once_t token;
    dispatch_once(&token, ^{

    sharedController = (FirstViewController *)[storyboard instantiateViewControllerWithIdentifier:@"firstViewController"];
    });

    return sharedController;
}

就像信号量一样使用token来保护块并确保它在程序运行期间只被调用一次;它不受竞争和同时读取的影响。

于 2013-01-26T00:16:23.433 回答
1

我很欣赏你更好地理解单例的目标,但我建议除非你必须这样做,否则不要使用单例。

我认为在大多数 UI 场景(我从来不需要)中拥有单例是不合适的。我建议使用以下方法之一在对象之间进行通信:

  • 保存对要与之通信的对象的引用。只需添加一个属性并保存对稍后需要调用的类的引用。如果它适用于您的场景,您可以将其设为弱参考。

  • 使用 iOS/Objective-c 应用程序中常见的委托模式。和上面一样,除了定义一个协议。通常调用该属性delegate。这允许其他视图使用通用接口进行通信。

  • 使用通知中心。在大多数情况下,我不喜欢这个选项,但是如果有很多视图可能需要了解的事件,并且您不想处理传递对对象的引用,那么它可能是一个不错的选择。

根据我的经验,单例最适合非 UI 代码,当您实际上需要依赖于在首次使用时实例化类的单例行为时。在您的情况下,您使用单例的唯一原因似乎是使该视图控制器可在整个应用程序中访问。

于 2013-01-26T00:43:33.240 回答
0

它应该工作。潜在问题:_webView 为 nil,[FirstViewController sharedController] 未返回有效引用。在 hideWebViewFromAnotherViewController 上设置断点并逐步执行,确保所有内容都在您认为的时候定义。

于 2013-01-25T23:17:34.827 回答