如何在类扩展中添加静态(存储)属性以生成单例? (SWIFT)

时间:2016-08-10 02:32:43

标签: ios objective-c swift extension-methods

我想将此代码转换为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

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

更新

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

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

3 个答案:

答案 0 :(得分:1)

在Swift中,您无法在扩展中添加静态变量。 如果可以访问,您可以在原始类中重试。否则,您可以修改代码:

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

答案 1 :(得分:0)

你总是可以将静态var驻留在扩展之外,或者作为一个单独的类,或者作为一个简单的全局变量(无论如何都是静态变量)。

例如:

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

答案 2 :(得分:0)

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