today I got an error with an explanation :) There's only one problem: I don't understand it :( So what am I doing wrong when I get this error?
2012-04-30 03:04:35.737 Barz[21961:11903] An instance 0x7491960 of class BarAnnotation was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. Here's the current observation info:
<NSKeyValueObservationInfo 0x74a18b0> (
<NSKeyValueObservance 0x74a1700: Observer: 0x747f2b0, Key path: coordinate, Options: <New: NO, Old: NO, Prior: YES> Context: 0x0, Property: 0x74a11c0>
)
Not that I did NOT add any observer manually, I just remove and add "BarAnnotation" (my custom MKAnnotation) to my mapView in the method viewWillAppear?
I'm also not quite sure if I understood who is observing whom: Is my mapView observing all of the MKAnnotations? Or is my mapViewController (== mapView's delegate) observing? And why does it behave like that if I disabled dragging?
Hope someone can help me and answer some of these questions :)
I've seen this happen when the annotation's coordinates are invalid. Have you checked that?
Related
Sorry this question may sound "subjective" but I think it should have a pretty definitive answer. I have a class "LocationManager" that I want to manage my Core Location logic. I have two options:
LocationManager has a strong property referencing an instance of CLLocationManager. LocationManager is a delegate of CLLocationManager and receives location updates from it as such.
LocationManager is a subclass of CLLocationManager, and says self.delegate = self so that it can receive its own location updates.
I'm curious which of these options is considered the "right" thing to do, I'm sure that there must a be a preferred way. Thanks!
Subclassing CLLocationManager and setting its delegate to self should not be done because it breaks the contract of CLLocationManager. As the class is currently defined, it has a delegate property. This property serves as a contract which states that you may set this property to some other object, and this object will receive delegate notifications. If you subclass CLLocationManager (let's call it MyLocationManager), and if the delegate property of the object points to itself, then you will most likely create a situation where MyLocationManager only works as promised if the user does not use the delegate property for his own purposes. From a users point of view, MyLocationManager is a CLLocationManager without a usable delegate property. This violates Liskovs Substitution Principle, btw. The question to ask here is: would MyLocationManager still work, if some ViewController class decides to use it and have its delegate property point to itself (the ViewController)?
Furthermore, it is no longer "delegation", if you say self.delegate = self. So I would say it is preferrable to use variant 1.
Thanks for the question.
Yes you can do this with no problem. I've a subclass of UITextField which is its own delegate.
The first option seems right to me because it doesn't make a ton of sense to subclass CLLocationManager (#2). What functionality would you be adding to it? If you're not adding anything to it why subclass?
All you care about is encapsulating the messages about location updates. I'd say you're using the delegate/protocol pattern acceptably in the first case.
And Jef is right, there are times where a subclass of another class can be set as its own delegate. Though you need to be careful about how that object responds to certain messages.
I am trying to use the mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated method to limit the region of my mapview but whenever I make a call to my mapview's region ([self.userMapView setRegion:regionLimit] ), it gives me a EXC_BAD_ACCESS error.
This error is thrown no matter what property I try to call from my mapView. I have my mapview set to the mapview with a proper outlet, and I was even able to call the set region in the viewDidLoad message.
How can I keep these properties from throwing the bad access error? If no can answer, can anyone direct me to a resource explaining how to debug something like this? Thanks.
See here for his to debug EXC_BAD_ACCESS errors and common mistakes that cause them. In your case, I'll bet your property is long dead and recycled, or was never initialized in the first place.
My question is pretty simple: are gesture recognizers and KVOs cleared when UIViewController is set to nil?
I have a project where the user can create and delete some complex UIViewController based instances. These are stored in an NSMutableArray.
If I just delete the instance from the array and then set it to nil (which I guess is superfluous) will all the #properties of the instance get cleared (assuming there are no other references to them)?
EDIT
I get the alert (error) below when I don't manage the KVOs - so I guess the answer is 'no'
An instance 0xce26d40 of class Track was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. Here's the current observation info:
(
Context: 0x0, Property: 0x7530300>
Context: 0x0, Property: 0x75320f0>
An object owns its '#properties' (assuming that they are strong or retain). And a view owns any gesture recognizers that are added to it. So when the object is deallocated, its properties and recognizers will be released, and deallocated if no one else owns them.
Key value observers and notification observers need to be manually unsubscribed before they get deallocated.
I am using a custom map annotation class for map view in iPhone. Whenever I pop my map view from navigation bar stack I usually see some warnings in console.
MapAnnotation was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. Here's the current observation info:
I am not using KVO in my code hence not able to understand why I am receiving these warnings
Latitude and Longitude have differing bounds:
(-90, 90) for Lat
(-180, 180) for Long
Passing a value outside of those bounds will cause the custom class to be deallocated and therefore giving you the error that you're receiving. Make sure that you are passing the correct values for both Latitude and Longitude.
It would be really nice if Apple passed a bounding error for this instead of an early release error. That would've saved me roughly 5 hours worth of time
I was getting the same error as you:
An instance 0xa975400 of class xxxxxx was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. Here's the current observation info:
<NSKeyValueObservationInfo 0xa980eb0> (
<NSKeyValueObservance 0xa980e70: Observer: 0xa94f8a0, Key path: coordinate, Options: <New: NO, Old: NO, Prior: YES> Context: 0x0, Property: 0xa980ef0>
As pointed here it was caused because I was adding a MKAnnotation with an invalid coordinate to a MKMapView.
My solution was to create a function to check the coordinate valid.
Place+MKAnnotation.m
I created a category of my Place class and
#import "Place.h"
#import <MapKit/MapKit.h>
#interface Place (MKAnnotation) <MKAnnotation>
- (BOOL)coordinateIsValid;
...
#end
Place+MKAnnotation.m
#implementation Place (MKAnnotation)
- (BOOL)coordinateIsValid
{
return CLLocationCoordinate2DIsValid(CLLocationCoordinate2DMake([self.latitude doubleValue],[self.longitude doubleValue]));
}
...
#end
I only add the annotation in my ViewController if the coordinate is valid.
if([p coordinateIsValid]) {
[self.mapView addAnnotation:p];
}
Fixed it. I was using a wrong pair of latitude and longitude in annotations, I have changed the same and now everything seems to be perfect and warning has been disappeared as well.
Are you autoreleasing your annotation before adding it to the MapView?
If so, try just allocating it, add it to the MapView, then release it.
I have an object that is interested in knowing when the region of a MKMapView is changed. This object is not the delegate of the map view, however. I'm trying the following, where map is a MKMapView:
[map addObserver:self forKeyPath:#"region" options:0 context:nil];
However, observeValueForKeyPath:ofObject:change:context: isn't being called back.
As an interim solution, I have the map's delegate letting this other object know when the map region is changed, but I'd like to uncouple the two objects as they aren't really related.
In Cocoa (Touch), properties of framework objects are only guaranteed to be KVO-compliant if the documentation says so. The docs for -[MKMapView region] make no such claim, so you shouldn't try to use KVO upon it. Even if it happened to work, you'd have no guarantee of complete compliance, or of continued success.
Instead, you'll have to use the delegate method and message other objects from there. Possibly your delegate could broadcast an NSNotification to achieve a similar effect to KVO.