How can I add a static (stored) property in a class extension to make a singleton? (Swift)

匆匆过客 提交于 2020-01-05 04:43:08

问题


I want to convert this code into Swift. The Objective-C code here is making a singleton object(if I can describe as such). I can use dispatch_once_t to convert it, but I want to use a more elegant way which should be similar to "static let bundle: NSBundle!". But "static let bundle: NSBundle!" is not allowed in an extension since it doesn't allow stored properties.

So is it possible to convert the code without dispatch_once_t?

And I faced a problem that I can not have stored properties in a class extension

@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

My Swift Code:

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

Update:

Thanks to people's answerings. I do it like this now. I am not sure it's the best way/

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

回答1:


In Swift, you cannot add static variables in extensions. You can retry in the original class if accessible. Otherwise, you can modify the code like:

if let bundleURL2 = bundleURL
{
    return NSBundle(URL: bundleURL2)
}
else
{
    return NSBundle.mainBundle()
}



回答2:


You could always have the static var reside outside of the extension, either in a separate class or as a simple global variable (which static variables are anyway).

for example:

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



回答3:


You can also subclass NSBundle and add this property to it.



来源:https://stackoverflow.com/questions/38863358/how-can-i-add-a-static-stored-property-in-a-class-extension-to-make-a-singleto

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!