如何在类扩展中添加静态(存储)属性以制作单例? (迅速)

Posted

技术标签:

【中文标题】如何在类扩展中添加静态(存储)属性以制作单例? (迅速)【英文标题】:How can I add a static (stored) property in a class extension to make a singleton? (Swift) 【发布时间】:2016-08-10 02:32:42 【问题描述】:

我想将此代码转换为 Swift。这里的 Objective-C 代码正在创建一个单例对象(如果我可以这样描述的话)。我可以使用 dispatch_once_t 来转换它,但我想使用一种更优雅的方式,应该类似于“static let bundle: NSBundle!”。但是“static let bundle: NSBundle!”在扩展中是不允许的,因为它不允许存储属性。

那么是否可以在没有dispatch_once_t的情况下转换代码?

我遇到了一个问题,我不能在类扩展中存储属性

@implementation NSBundle (CTFeedback)

+ (NSBundle *)feedbackBundle

    static NSBundle *bundle = nil;
    static dispatch_once_t predicate;

    dispatch_once(&predicate, ^
        NSBundle *classBundle = [NSBundle bundleForClass:[CTFeedbackViewController class]];
        NSURL *bundleURL = [classBundle URLForResource:@"CTFeedback" withExtension:@"bundle"];

        if (bundleURL) 
            bundle = [NSBundle bundleWithURL:bundleURL];
         else 
            bundle = [NSBundle mainBundle];
        
    );

    return bundle;


@end

我的 Swift 代码:

extension NSBundle

    static func feedbackBundle()-> NSBundle
    
        static let bundle: NSBundle! //!! **Compiler Error here**

        let classBundle = NSBundle.init(forClass: CTFeedbackViewController.self)
        let bundleURL = classBundle.URLForResource("CTFeedback", withExtension: "bundle")

        if let bundleURL2 = bundleURL
        
            bundle = NSBundle(URL: bundleURL2)
        
        else
        
            bundle = NSBundle.mainBundle()
        

        return bundle;
    


更新:

感谢人们的回答。我现在这样做。我不确定这是不是最好的方法/

private class FeedbackBundle

    static let classBundle = NSBundle.init(forClass: CTFeedbackViewController.self)


extension NSBundle

    static func feedbackBundle()-> NSBundle
    
        let bundleURL = FeedbackBundle.classBundle.URLForResource("CTFeedback", withExtension: "bundle")
        if let bundleURL2 = bundleURL
        
            return NSBundle(URL: bundleURL2)!
        
        else
        
            return NSBundle.mainBundle()
        
    

【问题讨论】:

错误是什么,可以试试self 【参考方案1】:

在 Swift 中,您不能在扩展中添加静态变量。 如果可以访问,您可以在原始课程中重试。否则,您可以像这样修改代码:

if let bundleURL2 = bundleURL

    return NSBundle(URL: bundleURL2)

else

    return NSBundle.mainBundle()

【讨论】:

听起来很合理。【参考方案2】:

您始终可以让静态变量驻留在扩展之外,可以在单独的类中或作为简单的全局变量(无论如何都是静态变量)。

例如:

 private class FeedbackBundle
 
   static var bundle: NSBundle!
 

 extension NSBundle
 
     static func feedbackBundle()-> NSBundle
     
         let classBundle = NSBundle.init(forClass: CTFeedbackViewController.self)
         let bundleURL = classBundle.URLForResource("CTFeedback", withExtension: "bundle")

         if let bundleURL2 = bundleURL
         
             FeedbackBundle.bundle = NSBundle(URL: bundleURL2)
         
         else
         
             FeedbackBundle.bundle = NSBundle.mainBundle()
         

         return FeedbackBundle.bundle;
     
 

【讨论】:

这是怎样的单例模式?你总是重新分配FeedbackBundle.bundle 如果我将“FeedbackBundle”中的“bundle”设为单例,则 feedbackBundle 也可以是单例。我正在尝试从“静态让捆绑:NSBundle!= ...”开始。【参考方案3】:

您也可以继承 NSBundle 并将此属性添加到其中。

【讨论】:

它打破了我想要一个扩展方法的意图,所以我不喜欢子类。还是谢谢你:)

以上是关于如何在类扩展中添加静态(存储)属性以制作单例? (迅速)的主要内容,如果未能解决你的问题,请参考以下文章

如何在PHP类中扩展静态继承数组

PHP封装的一个单例模式Mysql操作类

设计模式简析(单例模式)

PHP中设计模式以及魔术方法

java设计模式之单例模式

单例模式详解