2016-08-04 50 views
0

Ich entwerfe eine App, die eine Funktion hat, die Benutzer ihren eigenen Pin hinzufügen lassen. Kürzlich habe ich festgestellt, dass meine App ein Speicherleck mit dem Titel "ContiguousArrayStorage" aufweist. Ich debuggte ein wenig und fand heraus, dass es ein Problem mit meiner for-Schleife in meinem Viewdidload war, aber ich bin mir nicht sicher, wie ich das Leck reparieren soll. Hier ist mein Code:Speicherleck in der Swift App aufgrund von ContiguousArrayStorage

@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) 



} 

Antwort

0

Ich stelle fest, Sie kümmert sich nicht festlegen, wie self in Ihrer Schließung zu erfassen. Wenn Sie sich in einem Einmalobjekt-Kontext (UIViewController) und einem asynchronen Abschluss befinden, müssen Sie sich immer darüber Gedanken machen. Sie müssen es als weak oder unowned erfassen. Kennen Sie Schließaufnahmelisten?

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

Das Muster, das ich verwenden ist self schwach zu erfassen und dann zu retten, wenn self worden null hat, zum Beispiel Die UIViewController wurde entlassen und geerntet. Wenn es noch da ist, nehme ich es vorübergehend stark mit einer lokalen Variablen in einer guard...let-Anweisung auf.

Kann nicht sagen, das ist das einzige Problem, weil wir die Deklarationen für Ihre Hilfsklassen nicht haben. Zum Beispiel wissen wir nicht, was Unfug Capital vorhat.

By the way, ist nur klar, dass Ihre for Schleife tut nicht Lauf bei viewDidLoad(). Sie registrieren lediglich einen Rückruf, der nur dann reagiert, wenn das Ereignis .Value auf dem Objekt StoringPin auftritt.