I got a crash from crashlytics. Probably it connected with weakSelf.
Crashed: com.apple.main-thread
EXC_BREAKPOINT 0x000000000defe
0 libobjc.A.dylib 0x224aea44 _objc_trap()
1 libobjc.A.dylib 0x224aeaa9 _objc_inform + 70
2 libobjc.A.dylib 0x224c8413 weak_register_no_lock + 210
3 libobjc.A.dylib 0x224c8993 objc_initWeak + 130
4 GPS_______appLite 0xd77b1 -[ModuleView observeValueForKeyPath:ofObject:change:context:] (ModuleView.m:232)
5 GPS_______appLite 0xd9287 -[ModuleSpeedometerView observeValueForKeyPath:ofObject:change:context:] (ModuleSpeedometerView.m:198)
6 Foundation 0x2349aa91 NSKVONotify + 52
7 Foundation 0x23479bef NSKeyValueNotifyObserver + 286
8 Foundation 0x23479847 NSKeyValueDidChange + 346
9 Foundation 0x23466599 -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] + 96
10 GPS_______appLite 0x12c393 -[GPSTracker private_updateCurrentStatisticsWithLocation:] (GPSTracker.mm:1887)
11 GPS_______appLite 0x12c1b9 -[GPSTracker private_addLocationToHistory:] (GPSTracker.mm:1870)
12 GPS_______appLite 0x12c6af -[GPSTracker private_processNewLocation:fromManager:] (GPSTracker.mm:1938)
13 GPS_______appLite 0x12c88b -[GPSTracker locationManager:didUpdateLocations:] (GPSTracker.mm:1953)
14 CoreLocation 0x28c5c493 (null) + 25830
15 CoreLocation 0x28c5765b (null) + 5806
16 CoreLocation 0x28c50725 (null) + 988
17 CoreFoundation 0x22cd5d91 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
18 CoreFoundation 0x22cd584d __CFRunLoopDoBlocks + 216
19 CoreFoundation 0x22cd41bf __CFRunLoopRun + 1806
20 CoreFoundation 0x22c232e9 CFRunLoopRunSpecific + 520
21 CoreFoundation 0x22c230d5 CFRunLoopRunInMode + 108
22 GraphicsServices 0x24213ac9 GSEventRunModal + 160
23 UIKit 0x272e80b9 UIApplicationMain + 144
24 GPS_______appLite 0x10adc7 main (main.m:15)
25 libdispatch.dylib 0x228cb873 (Missing)
and code
//ModuleView class
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if ([object isKindOfClass:[GPSTracker class]])
{
__weak GPSTracker *tracker = (GPSTracker *)object;
__weak __typeof__(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
if ([keyPath isEqualToString:NSStringFromSelector(#selector(trackerMode))])
{
[weakSelf trackerStateChanged];
}
else if ([keyPath isEqualToString:NSStringFromSelector(#selector(currentStatistics))])
{
id oldValue = [change objectForKey:NSKeyValueChangeOldKey];
if (!oldValue
|| [oldValue isKindOfClass:[NSNull class]])
{
// If statistics instance has been initialized
if (!weakSelf.shouldIgnoreUpdates)
{
[tracker.currentStatistics.time addUniqueObserver:weakSelf
forKeyPath:NSStringFromSelector(#selector(elapsed))
options:NSKeyValueObservingOptionNew];
}
}
[weakSelf trackerUpdate];
}
});
}
else if ([object isKindOfClass:[GPSTrackerTimeStatistics class]])
{
__weak __typeof__(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf timerUpdate];
});
}
}
for released version you can see crashes and line of code,
in xCode : Window-> Organizer-> Crashes
and select app and version from left panels
try "Exception Breakpoint"
Exception Breakpoint automatically add breakpoint to line has cause crash, and you can see the problem
to add Exception Breakpoint:
in xCode :
top menu -> Debug -> Breakpoints -> Create Exception Breakpoint...
and run again
Related
I'm checking self.next_id is not null why would this line crash? I can't reproduce the issue on my test devices. I only get crash reports from Crashlytics at this line.
-(Second*)getNextSecond:(BOOL)returnSelf{
Second* retValue = nil;
if(self.next_id){
//this line !!!!
retValue = [[SecondDatabase sharedManager] getSecond:[self.next_id stringValue]];
}
if (retValue == nil && returnSelf) {
return self;
}else{
return retValue;
}
}
This is my SecondDatabase sharedManager function:
#property NSMutableDictionary* dictionary;
- (id)init {
if (self = [super init]) {
_dictionary = [#{} mutableCopy];
}
return self;
}
+ (id)sharedManager {
static SecondDatabase *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
This is my getSecond function:
-(Second*)getSecond:(NSString*)idString{
return [_dictionary objectForKey:idString];
}
Where should I be investigating? Would this crash if dictionary didn't have object for key so that it returns NULL?
My crash report:
Crashed: com.apple.main-thread
EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x000007d8
Thread : Crashed: com.apple.main-thread
0 libobjc.A.dylib 0x3acd164c realizeClass(objc_class*) + 19
1 libobjc.A.dylib 0x3acd1715 realizeClass(objc_class*) + 220
2 libobjc.A.dylib 0x3acd1715 realizeClass(objc_class*) + 220
3 libobjc.A.dylib 0x3acd39ab lookUpImpOrForward + 74
4 libobjc.A.dylib 0x3acd3957 _class_lookupMethodAndLoadCache3 + 34
5 libobjc.A.dylib 0x3acd88b9 _objc_msgSend_uncached + 24
6 itsmysecond-ios 0x001287c7 -[Second getNextSecond:] (Second.m:93)
7 itsmysecond-ios 0x000fd5ff -[EBParallaxViewController adjustViewsToSeconds] (EBParallaxViewController.m:181)
8 itsmysecond-ios 0x000fd21d -[EBParallaxViewController scrollViewDidEndDecelerating:] (EBParallaxViewController.m:154)
9 UIKit 0x32ed6957 -[UIScrollView(UIScrollViewInternal) _stopScrollDecelerationNotify:] + 806
10 UIKit 0x32e0cd47 -[UIScrollView(UIScrollViewInternal) _stopScrollingNotify:pin:tramplingDragFlags:] + 466
11 UIKit 0x32e0cb6b -[UIScrollView(UIScrollViewInternal) _stopScrollingNotify:pin:] + 30
12 UIKit 0x32ed621b -[UIScrollView _smoothScrollWithUpdateTime:] + 3322
13 QuartzCore 0x32a06df3 CA::Display::DisplayLinkItem::dispatch() + 98
14 QuartzCore 0x32a06b9d CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 344
15 IOMobileFramebuffer 0x3577f75d IOMobileFramebufferVsyncNotifyFunc + 104
16 IOKit 0x31209451 IODispatchCalloutFromCFMessage + 248
17 CoreFoundation 0x304ddea9 __CFMachPortPerform + 136
18 CoreFoundation 0x304e8a67 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 34
19 CoreFoundation 0x304e8a03 __CFRunLoopDoSource1 + 346
20 CoreFoundation 0x304e71d7 __CFRunLoopRun + 1398
21 CoreFoundation 0x30451ebf CFRunLoopRunSpecific + 522
22 CoreFoundation 0x30451ca3 CFRunLoopRunInMode + 106
23 GraphicsServices 0x35357663 GSEventRunModal + 138
24 UIKit 0x32d9e14d UIApplicationMain + 1136
25 itsmysecond-ios 0x00109707 main (main.m:14)
26 libdyld.dylib 0x3b1dbab7 start + 2
[self.kvoController observe:user keyPath: #"fullName" options:NSKeyValueObservingOptionNew block:^(id observer, id object, NSDictionary *change) {
dispatch_async(dispatch_get_main_queue(), ^{
NSString *fullname = [change objectForKey:NSKeyValueChangeNewKey];
if ([fullname isKindOfClass:[NSString class]]) {
if (![weakSelf.fullnameLabel.text isEqualToString: fullname]) {
weakSelf.fullnameLabel.text = fullname;
[weakSelf.fullnameLabel sizeToFit];
}
}
});
}];
This code crashes on the 3rd line NSString *fullname = [change objectForKey:NSKeyValueChangeNewKey];
The crash log is as below:
Crashed: com.apple.main-thread EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x00002069
0 libobjc.A.dylib 0x38449612 objc_retain + 17
1 Retro 0x0013336b __33-[ProfileHeaderView observeUser:]_block_invoke_2491 (ProfileHeaderView.m:598)
2 libdispatch.dylib 0x38922833 _dispatch_call_block_and_release + 10
3 libdispatch.dylib 0x3892281f _dispatch_client_callout + 22
4 libdispatch.dylib 0x3892949f _dispatch_main_queue_callback_4CF$VARIANT$mp + 278
5 CoreFoundation 0x2d83b8f1 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
6 CoreFoundation 0x2d83a1c5 __CFRunLoopRun + 1300
7 CoreFoundation 0x2d7a4f0f CFRunLoopRunSpecific + 522
8 CoreFoundation 0x2d7a4cf3 CFRunLoopRunInMode + 106
9 GraphicsServices 0x326ca663 GSEventRunModal + 138
10 UIKit 0x300f016d UIApplicationMain + 1136
11 Retro 0x0007d253 main (main.m:16)
Any idea why it crashed because I can't replicate this on my device (the log is from crash reporter).
Team,
I got a crash when I perform below actions in my simulator,
> Navigated to Screen1 - > Screen2- > Screen3 -> Screen2 -> screen1
> Press home screen - Go to iPhone Settings screen -> Relaunch my application
> then perform the same steps (Screen1 - > Screen2- > Screen3 -> Screen2 -> screen1)
> perform the same steps Screen1 -> screen2 -> Screen3 -> CRASH on [super viewDidLoad]
I don't see any crash logs or console logs for the crash, but my debugger stops at this point.
Any idea why my application crashes only when I minimized and relaunch the application. If I don't minimize the application, everything works as expected.
Why I am not able to view any console logs for the crash?
Note: We tested on iOS6 device and there is no crash, this is observed only in iOS7 device. I can reproduce the crash only when I minimize the application, else it works fine.
seen this log only once,
2014-04-16 11:42:05.073 ADTCommercial[36614:60b] -[CALayerArray leading]: unrecognized selector sent to instance 0xac1a690
2014-04-16 11:42:05:077 ADTCommercial[36614:60b]
*÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷*
* An Exception Has Been Handled! *
Method:
-[ADT_TaskHomeList(Custom) tableView:didSelectRowAtIndexPath:] -
Exception Name:
NSInvalidArgumentException
Exception Reason:
-[CALayerArray leading]: unrecognized selector sent to instance 0xac1a690
StackTrace:
0 CoreFoundation 0x031af1e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x03d7e8e5 objc_exception_throw + 44
2 CoreFoundation 0x0324c243 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x0319f50b ___forwarding___ + 1019
4 CoreFoundation 0x0319f0ee _CF_forwarding_prep_0 + 14
5 ADTCommercial 0x005aa1d1 +[AMPListScreenTableViewCell getHeightForFont:numberOfLines:] + 113
6 ADTCommercial 0x0059dd80 -[AMPGeneratedListViewController invalidate] + 224
7 ADTCommercial 0x0059e4f8 -[AMPGeneratedListViewController setNumberOfLines:] + 360
8 ADTCommercial 0x0059d28e -[AMPGeneratedListViewController viewDidLoad] + 270
9 ADTCommercial 0x00107208 -[ADT_SystemDetails(Custom) viewDidLoad] + 72
10 UIKit 0x02122e10 -[UIViewController awakeFromNib] + 110
11 UIKit 0x022bbf67 -[UINib instantiateWithOwner:options:] + 1955
12 UIKit 0x022bdada -[NSBundle(UINSBundleAdditions) loadNibNamed:owner:options:] + 165
13 ADTCommercial 0x005c1f7b -[AMPViewManager loadView] + 811
14 ADTCommercial 0x005b6916 -[AMPScreenManager showScreen:withRow:createScreen:reloadPolicy:doReset:isModal:animated:navigationController:] + 3542
15 ADTCommercial 0x0058b1ec +[AMPStandardActions gotoAction:reloadPolicy:transactionStateChange:addToHistory:] + 252
16 ADTCommercial 0x002c4935 -[ADT_TaskHomeList(Custom) tableView:didSelectRowAtIndexPath:] + 901
17 UIKit 0x020f09a1 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1513
18 UIKit 0x020f0b14 -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 279
19 UIKit 0x020f510e __38-[UITableView touchesEnded:withEvent:]_block_invoke + 43
20 UIKit 0x020240aa ___afterCACommitHandler_block_invoke + 15
21 UIKit 0x02024055 _applyBlockToCFArrayCopiedToStack + 403
22 UIKit 0x02023e76 _afterCACommitHandler + 532
23 CoreFoundation 0x0317736e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
24 CoreFoundation 0x031772bf __CFRunLoopDoObservers + 399
25 CoreFoundation 0x03155254 __CFRunLoopRun + 1076
26 CoreFoundation 0x031549d3 CFRunLoopRunSpecific + 467
27 CoreFoundation 0x031547eb CFRunLoopRunInMode + 123
28 GraphicsServices 0x04e805ee GSEventRunModal + 192
29 GraphicsServices 0x04e8042b GSEventRun + 104
30 UIKit 0x02006f9b UIApplicationMain + 1225
31 ADTCommercial 0x0000642e main + 126
32 libdyld.dylib 0x044c4701 start + 1
33 ??? 0x00000001 0x0 + 1
*÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷*
-(void)tableView:(UITableView *)table didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
PMPCAccountInfoTabScreen *accountsInfoTabScreen = nil;
PMPCJobWrapUp *wrapUpScreen = nil;
NSString *screenPushedUnderJobWrapUp = #"SCREEN_PUSHED_UNDER_WRAP_UP";
#try {
switch (indexPath.row) {
case 0:
// PUSH THE ACCOUNT INFORMATION SCREEN
accountsInfoTabScreen = (PMPCAccountInfoTabScreen*)[[[PMPCScreenManager sharedScreenManager] getScreen:#"PMPCAccountInfoTabScreen"] view];
[accountsInfoTabScreen setSelectedTab:0];
[PMPCStandardActions gotoAction:#"PMPCAccountInfoTabScreen" reloadPolicy:PMPCScreenReloadAlways transactionStateChange:PMPCTransactionContinue addToHistory:YES];
[Commons setClipboardValueForKey:screenPushedUnderJobWrapUp value:[NSNumber numberWithBool:NO]];
break;
case 1:
// PUSH THE JOB DETAILS SCREEN
[PMPCStandardActions gotoAction:#"JobDetailsScreen" reloadPolicy:PMPCScreenReloadAlways transactionStateChange:PMPCTransactionContinue addToHistory:YES];
[Commons setClipboardValueForKey:screenPushedUnderJobWrapUp value:[NSNumber numberWithBool:NO]];
break;
case 2:
//[[PMPCDataClipboard sharedClipboard] setValueForKey:screenPushedUnderJobWrapUp value:[NSNumber numberWithBool:NO]];
[[PMPCDataClipboard sharedClipboard] removeValueForKey:screenPushedUnderJobWrapUp];
[Commons setClipboardValueForKey:screenPushedUnderJobWrapUp value:[NSNumber numberWithBool:NO]];
[PMPCStandardActions gotoAction:#"PMPCSystemDetails" reloadPolicy:PMPCScreenReloadAlways transactionStateChange:PMPCTransactionContinue addToHistory:YES];
break;
case 3:
// Add Items screen
[Commons setClipboardValueForKey:screenPushedUnderJobWrapUp value:[NSNumber numberWithBool:NO]];
[PMPCStandardActions gotoAction:#"PMPCAddedItemsList" reloadPolicy:PMPCScreenReloadAlways transactionStateChange:PMPCTransactionContinue addToHistory:YES];
break;
case 4:
// PUSH THE JOB WRAP UP SCREEN
//JobWrapUpObject *wrapUp = [Commons getJobWrapUpObject];
//[wrapUp resetValues];
wrapUpScreen = (PMPCJobWrapUp*)[[[PMPCScreenManager sharedScreenManager] getScreen:#"PMPCJobWrapUp"] view];
[wrapUpScreen setScrollToTop:YES];
[Commons setClipboardValueForKey:screenPushedUnderJobWrapUp value:[NSNumber numberWithBool:YES]];
[PMPCStandardActions gotoAction:#"PMPCJobWrapUp" reloadPolicy:PMPCScreenReloadAlways transactionStateChange:PMPCTransactionBegin addToHistory:YES];
break;
default:
break;
}
}
#catch (NSException *exception) {
ExceptionLog(exception);
}
#finally {
[PMPCLog trace:#"%s Ends",__PRETTY_FUNCTION__];
}
}
Thanks,
Ramesh
I'm getting a strange crash with the iAd error callback. Here is my crash log:
Exception Type: EXC_BAD_ACCESS Code: KERN_INVALID_ADDRESS at 0x2281
0com.apple.main-thread Crashed
0 libobjc.A.dylib objc_retain + 17
1 YouDoodle AdView.m line 265 -[AdContainerView requestGAD]
2 iAd -[ADBannerView _forwardErrorToDelegate:] + 254
3 iAd -[ADBannerView serverBannerViewDidFailToReceiveAdWithError:] + 178
4 iAd -[ADAdSpace setServiceAdSpace:] + 472
5 CoreFoundation __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
6 CoreFoundation _CFXNotificationPost + 1718
7 Foundation -[NSNotificationCenter postNotificationName:object:userInfo:] + 76
8 Foundation -[NSNotificationCenter postNotificationName:object:] + 30
9 iAd -[ADAdSheetProxy _adSheetConnectionLost] + 292
10 ... libdispatch.dylib _dispatch_call_block_and_release + 10
11 libdispatch.dylib _dispatch_client_callout + 22
12 libdispatch.dylib _dispatch_main_queue_callback_4CF$VARIANT$up + 274
13 CoreFoundation __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
14 CoreFoundation __CFRunLoopRun + 1300
15 CoreFoundation CFRunLoopRunSpecific + 522
16 CoreFoundation CFRunLoopRunInMode + 106
17 GraphicsServices GSEventRunModal + 138
18 UIKit UIApplicationMain + 1136
19 YouDoodle
AppDelegate.m line 129
main
http://crashes.to/s/c654d14dcfa
delegate callback for iAd:
- (void) bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
DLog(#"IAD Failed to load with error %#", error);
self.adBannerContainer.hidden = YES;
if (InternetAvailableWithAlert(NO))
{
if (self.gadAvailable)
{
self.gadBannerContainer.hidden = NO;
}
else
{
[self requestGAD];
}
}
}
- (void) requestGAD
{
GADRequest* request = [[GADRequest alloc] init];
#if TARGET_IPHONE_SIMULATOR
request.testDevices = #[GAD_SIMULATOR_ID];
#endif
self.gadBanner.rootViewController = (self.gadBanner.rootViewController ?: self.viewController);
[self.gadBanner loadRequest:request];
}
The iAd view delegate is a singleton which is never released. Even if it was released, the iAd class delegate property is a weak property so it should auto-nil.
#property (nonatomic, weak) id<ADBannerViewDelegate> delegate;
Ideas?
This was due to setting the Admob SDK root view controller back to itself, when the view controller has been deallocated, this crashes. Admob SDK uses an assign reference instead of weak which is why it crashed.
I'm trying to use a KVO example I got from an iPhone tutorial book, but get this exception
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '<UINavigationController: 0x139630>: An -observeValueForKeyPath:ofObject:change:context: message was received but not handled.
Key path: dataUpdated
Observed object: <FilterDetailsController: 0x1b9930>
Change: {
kind = 1;
}
Context: 0x0'
Call stack at first throw:
(
0 CoreFoundation 0x320d3987 __exceptionPreprocess + 114
1 libobjc.A.dylib 0x3271849d objc_exception_throw + 24
2 CoreFoundation 0x320d37c9 +[NSException raise:format:arguments:] + 68
3 CoreFoundation 0x320d3803 +[NSException raise:format:] + 34
4 Foundation 0x35c316e9 -[NSObject(NSKeyValueObserving) observeValueForKeyPath:ofObject:change:context:] + 60
5 Foundation 0x35bd4a3d NSKeyValueNotifyObserver + 216
6 Foundation 0x35bd46e5 NSKeyValueDidChange + 236
7 Foundation 0x35bcc3f5 -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] + 76
8 Foundation 0x35c30d87 _NSSetObjectValueAndNotify + 98
9 Lucid Dreaming App 0x000108e3 -[FilterDetailsController adjustFilterDetails:] + 138
10 CoreFoundation 0x3207afed -[NSObject(NSObject) performSelector:withObject:withObject:] + 24
11 UIKit 0x323b3ea5 -[UIApplication sendAction:to:from:forEvent:] + 84
12 UIKit 0x323b3e45 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 32
13 UIKit 0x323b3e17 -[UIControl sendAction:to:forEvent:] + 38
14 UIKit 0x323b3b69 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 356
15 UIKit 0x323b43c7 -[UIControl touchesEnded:withEvent:] + 342
16 UIKit 0x323a9d4d -[UIWindow _sendTouchesForEvent:] + 368
17 UIKit 0x323a96c7 -[UIWindow sendEvent:] + 262
18 UIKit 0x3239499f -[UIApplication sendEvent:] + 298
19 UIKit 0x323942df _UIApplicationHandleEvent + 5090
20 GraphicsServices 0x35472f03 PurpleEventCallback + 666
21 CoreFoundation 0x320686ff __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 26
22 CoreFoundation 0x320686c3 __CFRunLoopDoSource1 + 166
23 CoreFoundation 0x3205af7d __CFRunLoopRun + 520
24 CoreFoundation 0x3205ac87 CFRunLoopRunSpecific + 230
25 CoreFoundation 0x3205ab8f CFRunLoopRunInMode + 58
26 GraphicsServices 0x354724ab GSEventRunModal + 114
27 GraphicsServices 0x35472557 GSEventRun + 62
28 UIKit 0x323c7d21 -[UIApplication _run] + 412
29 UIKit ...
I start by
[advancedController addObserver:self.navigationController forKeyPath:#"dataUpdated" options:0 context:nil];
within self.navigation controller, I have the observation method defined:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(#"2 Observed change for: %#",keyPath);
// if (context == <#context#>) {
// <#code to be executed upon observing keypath#>
// } else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
// }
}
within advancedController I have a NSNumber property
#property(nonatomic,retain)NSNumber* dataUpdated;
When I hit a button, I expect the observer to fire.
- (IBAction)adjustFilterDetails:(id)sender {
self.dataUpdated = [NSNumber numberWithInt:[self.dataUpdated intValue]+1];
}
Do I need to implement some protocol or explicitly state that I will update the value? I read that NSKeyValueObserving is an "informal" protocol. Thank you for your help!
I have figured out the answer to my own question. I had the KVO protocol method defined within a ViewController, however, I have accidentally registered the Navigation controller for the View controller to observe the value. The correct object is found by getting the view controller like this:
[advancedController addObserver:(RootViewController*)self.navigationController. topViewController forKeyPath:#"dataUpdated" options:0 context:nil];
Your problem is the call to super. You shouldn't pass this method to super for properties that you observed yourself. You commented out the code that was there to help you with this.
A possible correct observation would be (note the context):
[advancedController addObserver:self.navigationController forKeyPath:#"dataUpdated" options:0 context:self];
And then the correct observer would be:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (context == self) {
NSLog(#"2 Observed change for: %#",keyPath);
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
Dave Dribin provides another approach to using context correctly, along with the backstory of why it's necessary, in Proper Key-Value Observer Usage.