由于ContiguousArrayStorage,Swift应用程序中的内存泄漏

时间:2016-08-04 02:46:43

标签: ios swift memory memory-leaks

我正在设计一款具有让用户添加自己的引脚功能的应用。最近,我发现我的应用程序内存泄漏,标题为“ContiguousArrayStorage”。我调试了一点,发现我的viewdidload中的for循环是一个问题,但我不知道如何修复泄漏。 这是我的代码:

@IBOutlet weak var AppleMap: MKMapView!

@IBOutlet weak var LogoutOutlet: UIButton!

@IBOutlet weak var OutletforAddPokemon: UIButton!

@IBOutlet weak var FindLocationOutlet: UIButton!

@IBOutlet weak var FilterOutlet: UIButton!

let locationManager = CLLocationManager()
let calendar: NSCalendar! = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)

var increment:Int = 0
var currentLoc:CLLocationCoordinate2D?
var centerMap = true
let StoringPin = FIRDatabase.database().reference().child("locations")

var Date = NSDate()

override func viewDidLoad() {
    super.viewDidLoad()

    AppleMap.delegate = self


    StoringPin.observeEventType(.Value, withBlock: {
        snapshot in
        if snapshot.value is NSNull {
            return
        }
        let val = snapshot.value as! [String : [String : AnyObject]]



        for key in val.keys {

            let latitudedata = val[key]!["latitude"] as! Double
            let longitudedata = val[key]!["longitude"] as! Double
            let namedata = val[key]!["name"] as! String
            let Username = val[key]!["Username"]
                as! String

            let DATE = val[key]!["Date"]
                as! String

            let NumberOflikesforuser = val[key]!["Likes"] as! Int


            let NumberOfDislikesforuser = val[key]!["Dislikes"] as! Int

            let coord = CLLocationCoordinate2D(latitude: latitudedata, longitude: longitudedata)

            let artwork = Capital(title: "\(namedata)", coordinate: coord, info: "HI", username: Username, NumofLikes: NumberOflikesforuser,NumofDisLikes: NumberOfDislikesforuser, UIDSTring: UID, date: DATE, color: MKPinAnnotationColor.Green)
            artwork.subtitle = DATE

            print("k")





           let permastringforemail:String = Username

            print(++self.increment)
            print(UID)
           print(permastringforemail)

           stringforemail = permastringforemail

            Arrayforpins.append(artwork)

            self.AppleMap.addAnnotation(Arrayforpins[Arrayforpins.count - 1])






            for Capital in Arrayforpins {
              self.AppleMap.addAnnotation(Capital)


            }


        }


    })







    print(LogoutOutlet)
    LogoutOutlet.layer.cornerRadius = 4

    FindLocationOutlet.layer.cornerRadius = 4
    OutletforAddPokemon.layer.cornerRadius = 4
    //FilterOutlet.layer.cornerRadius = 4

    self.locationManager.requestAlwaysAuthorization()
    self.locationManager.requestWhenInUseAuthorization()

    if CLLocationManager.locationServicesEnabled() {
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
        locationManager.startUpdatingLocation()
    }


    let annotationView = MKAnnotationView()
    let detailButton: UIButton = UIButton.init(type: .DetailDisclosure) as UIButton
    annotationView.rightCalloutAccessoryView = detailButton



}
let regionRadius: CLLocationDistance = 1000



func centerMapOnLocation(location: CLLocation) {
    let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate,
                                                              regionRadius * 2.0, regionRadius * 2.0)
    AppleMap.setRegion(coordinateRegion, animated: true)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let locValue:CLLocationCoordinate2D = manager.location!.coordinate

    if CLLocationManager.authorizationStatus() == .AuthorizedWhenInUse {
        AppleMap.showsUserLocation = true
    } else {
        locationManager.requestWhenInUseAuthorization()
    }

    print("update")

    currentLoc = locValue

    if centerMap {
        centerMap = false
        centerMapOnLocation(CLLocation(latitude: currentLoc!.latitude, longitude: currentLoc!.longitude))
    }

}


@IBAction func SendtoSelector(sender: AnyObject) {

    self.performSegueWithIdentifier("SeguetoSelector", sender: self)

}


@IBAction func FilterFunc(sender: AnyObject) {
    self.performSegueWithIdentifier("SeguetoFilter", sender: self)
}


@IBAction func FindLocation(sender: AnyObject) {
    centerMapOnLocation(CLLocation(latitude: currentLoc!.latitude, longitude: currentLoc!.longitude))


}

@IBAction func Logout(sender: AnyObject) {
    LO = true
    self.performSegueWithIdentifier("BacktoLoginScreen", sender: self)
}



override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    locationManager
    if IndexBoolean == true{
        //let annotationView = MKPinAnnotationView()
        print("Hi")
        let artwork = Capital(title: "\(pickerDataSource[chosenindex])", coordinate: CLLocationCoordinate2D(latitude: currentLoc!.latitude, longitude: currentLoc!.longitude), info: "HEY", username: stringforemail, NumofLikes: NumberOfLikes, NumofDisLikes: NumberOfDislike, UIDSTring: UID, date: stringfordate2, color: MKPinAnnotationColor.Green)

        //print(now)
        print(chosenindex)
        artwork.title = "\(pickerDataSource[chosenindex])"
        //artwork.subtitle = stringfordate
      AppleMap.addAnnotation(artwork)
        //annotationView.pinColor = artwork.Green

            Arrayforpins.append(artwork)
        print(stringforemail)


   AppleMap.addAnnotation(Arrayforpins[Arrayforpins.count - 1])

        for Capital in Arrayforpins{
        AppleMap.addAnnotation(Capital)

        }
        IndexBoolean = false

        var formatter = NSDateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
        formatter.timeZone = NSTimeZone(abbreviation: "Central Time")
        var utcTimeZoneSTR = formatter.stringFromDate(Date)


        stringfordate = "\(utcTimeZoneSTR)"

        let uid = NSUUID().UUIDString
        UID = uid
        StoringPin.child(uid).setValue(["name" :   pickerDataSource[chosenindex],
            "latitude" : currentLoc!.latitude,
            "longitude" : currentLoc!.longitude,"Array Position" : chosenindex,"Username": stringforemail, "Likes": NumberOfLikes2, "Dislikes":
            NumberOfDislike, "UID": UID, "Date": stringfordate])


        if FilterBoolean == true {
            print("b")
            if FilterDataSource[Intforfilter] != stringforname {
                print("k")
                //self.AppleMap.viewForAnnotation(artwork)?.hidden = true
                FilterBoolean == false

            }

            //else {
            //                    print("m")
            //                    self.AppleMap.removeAnnotation(artwork)
            //
            //                }

            FilterBoolean == false

        }


    }

}

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {

    let identifier = "Capital"
    print(++increment)

    if annotation.isKindOfClass(Capital.self) {
        print("CAPITAL")
        if let annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier) {
            annotationView.annotation = annotation
            return annotationView
        } else {
            let annotationView = MKPinAnnotationView(annotation:annotation, reuseIdentifier:identifier)
            annotationView.enabled = true
            annotationView.canShowCallout = true
           //annotationView.pinColor = MKPinAnnotationColor.Green
            let btn = UIButton(type: .DetailDisclosure)

            annotationView.rightCalloutAccessoryView = btn
            return annotationView
        }
    }

    return nil
}

func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
    let capital = view.annotation as! Capital
    let placeName = capital.title
    let placeInfo = capital.info
    let UserName = capital.username

    stringforname = view.annotation!.title!!
    coords = view.annotation!.coordinate
    stringforemail = capital.username
    stringfordate2 = capital.date

    NumberOfLikes2 = capital.NumofLikes

    UID = capital.UIDSTring

    print(stringforname)
    print(UID)

    self.performSegueWithIdentifier("SegueToInfo", sender: self)



}

1 个答案:

答案 0 :(得分:1)

我注意到您并没有注意如何在关闭中指定self。在一次性对象上下文(UIViewController)和异步闭包时,您总是要担心这一点。您需要将其捕获为weakunowned。你熟悉闭包捕获列表吗?

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097-CH20-ID56

我使用的模式是弱self,如果self变为零,则保释,例如UIViewController已被解雇和收获。如果它仍然存在,我会使用guard...let语句中的局部变量暂时捕获它。

withBlock: { [weak self] (snapshot) in
    guard let s = self else { 
        print("Callback called after view unloaded")
        return 
    }
    // now use 's' instead of 'self'
    ...
}

不能说这是唯一的问题,因为我们没有帮助类的声明。例如,我们不知道Capital的恶作剧是什么。

顺便说一句,只需明确for循环 <{1}}。您只是注册一个回调,该回调仅在viewDidLoad()对象发生.Value事件时才会做出反应。