2017-01-31 72 views
1

我有一个核心数据项目,我从多个来源检索数据。并不是所有的数据都会被保存,所以我创建了一个结构来在保存之前传递数据。单身人士不按要求工作

struct SearchResult { 
    var myURL: String? 
    var myHeadline: String? 

    init() {} 

    init(myURL: String, myHeadline: String) { 
     self.myURL = myURL 
     self.myHeadline = myHeadline 
    } 
} 

因为我想在一个UITableView显示部分,我创建了一个struct,以及:

struct ResultsObjects { 
    var sectionName: String? 
    var sectionObjects = [SearchResult]() 

    init() {} 

    init(sectionName: String) { 
     self.sectionName = sectionName 
    } 
} 

最后,我创建了一个singleton继续持有SearchResult对象来保存它们在之前managedObjectContext

class SearchResultsArray { 
    static let sharedInstance = SearchResultsArray() 
    var resultsObjectsArray = Array<ResultsObjects>() 
    fileprivate init() {} 
} 

我的目标是让SearchResultsArray类通过多类访问,并能够倾倒ResultsObjects到它在一个类中,看到在另一个ResultsObjects

MyViewController,我实例化SearchResultsArray如下:

var resultsObjectsArray = SearchResultsArray.sharedInstance.resultsObjectsArray 

我有一个UITableViewController,我使用resultsObjectsArray填充。

MyViewController上,一个按钮调用一个方法,该方法使用MyParserClass中的方法来解析网页。这也适用。

MyParserClass声明中相同的方式一个resultsObjectsArray作为MyViewController

var resultsObjectsArray = SearchResultsArray.sharedInstance.resultsObjectsArray 

MyParserClass,一种方法被称为创建SearchResult对象,他们转储到ResultsObjects和它们附加到SearchResultsArray.resultsObjectsArray。这工作正常。我在下面一行扔在倾入resultsObjectsArray创建ResultsObjects方法:

print("\(resultsObjectsArray.count) ResultsObjects in SearchResultsArray") 
delegate.updateSearchResults() 

MyViewControllerupdateSearchResults委托方法扔了打印语句,它返回0,不管是什么MyParserClass说是在那里就在调用委托方法之前。

该应用程序不会崩溃,但它似乎像我有单身的问题。任何建议重新:我做错了什么是不胜感激。

+0

你见过这个帖子http://stackoverflow.com/questions/26742138/singleton-in-swift 它表明我们应该声明类'final'来确保我们不会获得倍数 - 可能值得检查 – Russell

+1

数组是快速值类型。您不能使用实例变量来引用该数组。您必须始终使用'SearchResultsArray.sharedinstance.resultsObjectsArray' – Paulw11

+0

@ Paulw11哇!我知道我错过了简单的事情,但哇!非常感谢你的回复。我非常感谢。 – Adrian

回答

1

数组是在迅速值类型;当分配的阵列,以一个变量,然后该变量分配给另一个,第二可变指原始数组的副本,而不是原始数组(原则上,为了提高效率,数组在复制时复制,而不是赋值,但结果相同),因此对原始数组所做的更改不会反映到第二个变量的数组中。

考虑

var someArray = [Int]() 
var someOtherVariable = someArray 
someArray.append(2) 

someArray将包含一个值,而someOtherVariable仍然是空的。

一个解决方案始终使用SearchResultsArray.sharedinstance.resultsObjectsArray而不是本地变量/属性。

也许更好的方法是通过提供一些函数来操作它,将数组封装在单例类中。例如;

class SearchResultsArray { 
    static let sharedInstance = SearchResultsArray() 
    var resultsObjectsArray = Array<ResultsObjects>() 

    public var results: [ResultsObjects] { 
     get { 
      return resultsObjectsArray 
     } 
    } 


    public func add(results: ResultsObjects) { 
     resultsObjectsArray.append(results) 
    } 


    fileprivate init() {} 
} 

由于results现在是一个只读属性和一个单独的add功能存在,类更清楚地定义了它的语义。

+0

非常感谢你。我学到了很多! – Adrian

+0

也添加一个清除/重置命令 – muescha

+1

当然,你可以。这只是一个例子,而不是一个完整的解决方案。 – Paulw11

0

我以非常相似的方式使用单例 - 但我对它的定义完全不同。

编辑 - 不同,现在在我的情况下取代:-(

在单件DataModelInstance,我有这个

class DataModelInstance : NSObject, NSCoding 
{ 
    // define all of the variables I need within the singleton 

    class var sharedInstance : DataModelInstance 
    { 
     struct Singleton 
     { 
      static let instance = DataModelInstance() 
     } 
     return Singleton.instance 
    } 

    // everything else that I need in the class... 
} 

,然后在每个需要访问类的,我定义可变

var dataModel = DataModelInstance.sharedInstance 
+1

其内的DataModelInstance?你可以添加一个小的DataModelInstance来让这个更清楚如何“在单身人士里面”它是 – muescha

+0

好的 - 我已经更新了答案。我没有包含任何NSCoding方法或我已经实现的任何数据级别的方法,但是这应该足以让我的所有ViewController都可以使用singleton – Russell

+2

@Russell:定义Singleton的方法是superseeded。现在,您只需按照OP在问题中所做的方式定义一个单例。 –