在函数内部设置类变量值,但在任何其他类/功能中调用时返回nil

时间:2015-05-04 07:46:31

标签: ios arrays xcode swift

编辑:答案在下面的注释中,我必须使用completionHandler才能进行异步调用。非常感谢Gasim的帮助。

在一个名为NetworkManager的类中,它有一个sharedInstance结构,允许我调用其他类中的函数,我声明public var urlArray = []这是一个空数组,不是任何函数的一部分。

在一个名为fetchLatestPosts的函数中,我正在解析JSON数据并下载一些像var photoURLArray: NSArray = responseDictionary.valueForKeyPath("data.images.standard_resolution.url") as NSArray这样的数组返回的相关URL,然后尝试设置self.urlArray = photoURLArray因为它允许我在函数之外设置photoURLArray的值。

问题在于,当我尝试将NetworkManager.sharedInstance.urlArray的值设置为不同方法中的函数时,结果返回nil。

这是因为在我将photoURLArray函数中的值设置为fetchLatestPosts之前,xCode认为我正在使用该值调用变量吗?有没有办法让我设置在函数内调用的数组的值,以便允许我在其他类中访问它的值?

我问这个的原因是因为我不想在我的tableViewCell类中进行JSON解析,因为否则每次出现新单元格时我都会对Instagram API进行大量调用。我已经被困在这个问题上一天左右,如果有人能帮我解决这个问题,我会很感激!

    public func fetchLatestPosts(tag: String) {

        var userDefaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
        var accessTokenQuery: AnyObject? = userDefaults.objectForKey("accessToken")

        if (accessTokenQuery == nil)
        {
            // Logging user in to IG
            SimpleAuth.authorize("instagram", completion: { (responseObject: AnyObject!, error: NSError!) -> Void in
                var IGDictionary: NSDictionary = responseObject as NSDictionary
                let credentials: AnyObject! = IGDictionary["credentials"]
                let accessToken: AnyObject! = credentials["token"]
                println("Access token: \(accessToken)")

                userDefaults.setObject(accessToken, forKey: "accessToken")
                userDefaults.synchronize()
            })

        } else {
            println("User is already logged in")

            // Load some posts
            var session: NSURLSession = NSURLSession.sharedSession()
            var accessToken: NSString = userDefaults.objectForKey("accessToken") as NSString
            var urlString: NSString =  NSString(format: "https://api.instagram.com/v1/tags/\(tag)/media/recent?access_token=%@", accessToken)
//            println(urlString)
            var url = NSURL(string: urlString)!
            var request: NSURLRequest = NSURLRequest(URL: url)
            var task: NSURLSessionDownloadTask = session.downloadTaskWithRequest(request, completionHandler: { (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in

                // Sorting JSON into dictionary
                var data: NSData = NSData(contentsOfURL: location)!
                var responseDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as [String: AnyObject]!

                // Getting photo URLs
                var photos: NSArray = responseDictionary.valueForKeyPath("data.images.standard_resolution.url") as NSArray
//                println("photos: \(photos)")

                self.IGDictionary = responseDictionary
                self.photoItems = photos
//                println("photoItems: \(self.photoItems)")


            })
            task.resume()
        }
    }

1 个答案:

答案 0 :(得分:0)

这就是我喜欢这样做的方式,因为我希望将请求部分与我真正想要做的事情分开,一旦完成:

public func fetchLatestPosts(tag: String, successHandler: (NSDictionary, NSArray) -> Void) {

    var userDefaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
    var accessTokenQuery: AnyObject? = userDefaults.objectForKey("accessToken")

    if (accessTokenQuery == nil)
        // ...
    } else {

        // ...
        var task: NSURLSessionDownloadTask = session.downloadTaskWithRequest(request, completionHandler: { (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in

            var data: NSData = NSData(contentsOfURL: location)!
            var responseDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as [String: AnyObject]!

            var photos: NSArray = responseDictionary.valueForKeyPath("data.images.standard_resolution.url") as NSArray

            successHandler(responseDictionary, photos);
        })
        task.resume()
    }
}

和示例用法:

override func viewDidLoad() {
    super.viewDidLoad();
    self.fetchLatestPosts("SomeTag", successHandler: {
        (responseDictionary, photos) in
        self.photos = photos;
        self.IGDictionary = responseDictionary;
        // reload collection view data or do whatever you need
        self.collectionView.reloadData();
    });
}

另外,我建议您查看SwiftyJSON。你使用它的那一刻就会爱上它。