2013-05-14 70 views
1

以下是發生了什麼事情:我有一個單身監視設備的事件存儲區以進行更改。我有一個名爲events的房產,我已包裹在eventsSignalRACSignalKVO通知的間歇性崩潰

_eventsSignal = [RACAble(self.events) startWith:nil]; 

當應用程序完成啓動,它會提示使用requestAccessToEntityType:completion:訪問日曆(標準方法)的用戶。完成塊執行在後臺排隊,所以我派回主隊列:從事件存儲

-(void)promptForAccess { 
    [_store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) { 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self willChangeValueForKey:EKEventManagerAccessibleKeyPath]; 
      _accessible = granted; 
      [self didChangeValueForKey:EKEventManagerAccessibleKeyPath]; 

      if (_accessible) { 
       // load events 
       [_store reset]; 
       [self refresh]; 
      } 
     }); 
    }]; 
} 

調用[self refresh]加載新的事件,然後調用

[self didChangeValueForKey:@"events"]; 

在這條線,該應用程序崩潰。

-[__NSCFString sourceType]: unrecognized selector sent to instance 0x200d6c80 

完整的堆棧跟蹤如下。我嘗試刪除調度調用,總是在主線程調度程序上安排_eventSignal,並且隨時隨地查看我正在訂閱事件信號(這一切看起來不錯)。任何我可能會錯過的東西?

編輯: 我把問題隔離到下面的代碼。如果nextEventSignal完全訂閱,那麼崩潰發生在大約一半的時間。如果我從combineLatest:reduce呼叫中刪除第二個信號,那麼它不會崩潰。

RACSignal *nextEventSignal = [[RACSignal combineLatest:@[eventManager.eventsSignal, eventManager.nextEventSignal, timerSignal] reduce:^id (NSArray *eventArray, EKEvent *nextEvent, NSDate *fireDate){ 
    NSArray *filteredArray = [[eventArray filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL (EKEvent *event, NSDictionary *bindings) { 
     return [event.endDate isLaterThanDate:[NSDate date]] && !event.isAllDay; 
    }]] sortedArrayUsingComparator:^NSComparisonResult (id obj1, id obj2) { 
     return [[obj1 startDate] compare:[obj2 startDate]]; 
    }]; 

    if (filteredArray.count == 0) { 
     if (nextEvent.isAllDay) { 
      return nil; 
     } 
     else { 
      return nextEvent; 
     } 
    } else { 
     return filteredArray[0]; 
    } 
}] throttle:0.25f]; 

這是碰撞日誌。

thread #1: tid = 0x2503, 0x3b40f944 libobjc.A.dylib`objc_exception_throw, stop reason = breakpoint 2.1 
frame #0: 0x3b40f944 libobjc.A.dylib`objc_exception_throw 
frame #1: 0x33717f30 CoreFoundation`-[NSObject(NSObject) doesNotRecognizeSelector:] + 184 
frame #2: 0x3371664c CoreFoundation`___forwarding___ + 392 
frame #3: 0x3366e208 CoreFoundation`__forwarding_prep_0___ + 24 
frame #4: 0x33e0442c EventKit`-[EKCalendar type] + 68 
frame #5: 0x33e49e10 EventKit`-[EKCalendar description] + 84 
frame #6: 0x33f7d204 Foundation`_NSDescriptionWithLocaleFunc + 88 
frame #7: 0x336f5430 CoreFoundation`__CFStringAppendFormatCore + 11160 
frame #8: 0x3366c8a2 CoreFoundation`_CFStringCreateWithFormatAndArgumentsAux + 74 
frame #9: 0x33f7ccfc Foundation`+[NSString stringWithFormat:] + 60 
frame #10: 0x33e5427c EventKit`-[EKCalendarItem description] + 228 
frame #11: 0x33e4ccae EventKit`-[EKEvent description] + 46 
frame #12: 0x336a35d0 CoreFoundation`-[NSArray descriptionWithLocale:indent:] + 680 
frame #13: 0x33f7d1f0 Foundation`_NSDescriptionWithLocaleFunc + 68 
frame #14: 0x336f5430 CoreFoundation`__CFStringAppendFormatCore + 11160 
frame #15: 0x3366c8a2 CoreFoundation`_CFStringCreateWithFormatAndArgumentsAux + 74 
frame #16: 0x33f7ccfc Foundation`+[NSString stringWithFormat:] + 60 
frame #17: 0x0010102a Upcoming`-[RACTuple description](self=0x1ed6dee0, _cmd=0x391cb2ce) + 182 at RACTuple.m:62 
frame #18: 0x33f7d204 Foundation`_NSDescriptionWithLocaleFunc + 88 
frame #19: 0x336f5430 CoreFoundation`__CFStringAppendFormatCore + 11160 
frame #20: 0x3366c8a2 CoreFoundation`_CFStringCreateWithFormatAndArgumentsAux + 74 
frame #21: 0x33f873de Foundation`-[NSString initWithFormat:arguments:] + 26 
frame #22: 0x000f9e50 Upcoming`-[RACStream setNameWithFormat:](self=0x1eda2a70, _cmd=0x0012e18b, format=0x001ad984) + 436 at RACStream.m:56 
frame #23: 0x000f26a2 Upcoming`+[RACSignal(self=0x001ab424, _cmd=0x0012e129, value=0x1ed6dee0) return:] + 222 at RACSignal.m:165 
frame #24: 0x000fa926 Upcoming`__29-[RACStream(.block_descriptor=0x1edf57b0, value=0x1ed52170) map:]_block_invoke + 86 at RACStream.m:91 
frame #25: 0x000fa13c Upcoming`__36-[RACStream(.block_descriptor=0x200f3970, value=0x1ed52170, stop=0x2fdc1580) flattenMap:]_block_invoke_2 + 44 at RACStream.m:72 
frame #26: 0x000f39f4 Upcoming`__29-[RACSignal(.block_descriptor=0x200f3b70, x=0x1ed52170) bind:]_block_invoke178 + 56 at RACSignal.m:243 
frame #27: 0x000ffbb6 Upcoming`-[RACSubscriber sendNext:](self=0x200f3a90, _cmd=0x00124ec2, value=0x1ed52170) + 294 at RACSubscriber.m:69 
frame #28: 0x000deb04 Upcoming`__43-[RACSignal(.block_descriptor=0x200f3cc0) combineLatestWith:]_block_invoke_2 + 304 at RACSignal+Operations.m:462 
frame #29: 0x000ded76 Upcoming`__43-[RACSignal(.block_descriptor=0x200f3df0, x=0x20196dc0) combineLatestWith:]_block_invoke463 + 282 at RACSignal+Operations.m:469 
frame #30: 0x000ffbb6 Upcoming`-[RACSubscriber sendNext:](self=0x200f3d30, _cmd=0x00124ec2, value=0x20196dc0) + 294 at RACSubscriber.m:69 
frame #31: 0x000f3694 Upcoming`__29-[RACSignal(.block_descriptor=0x1eda3610, x=0x20196dc0) bind:]_block_invoke_2157 + 76 at RACSignal.m:222 
frame #32: 0x000ffbb6 Upcoming`-[RACSubscriber sendNext:](self=0x1edea190, _cmd=0x00124ec2, value=0x20196dc0) + 294 at RACSubscriber.m:69 
frame #33: 0x000f2746 Upcoming`__31+[RACSignal(.block_descriptor=0x1edc5dd0, subscriber=0x1edea190) return:]_block_invoke + 106 at RACSignal.m:166 
frame #34: 0x000f6a30 Upcoming`__37-[RACSignal(.block_descriptor=0x2fdc1c20) subscribe:]_block_invoke300 + 80 at RACSignal.m:386 
frame #35: 0x00100aca Upcoming`-[RACSubscriptionScheduler schedule:](self=0x200c0e00, _cmd=0x0012de2e, block=0x2fdc1c20) + 542 at RACSubscriptionScheduler.m:40 
frame #36: 0x000f650c Upcoming`-[RACSignal(self=0x2019a790, _cmd=0x0012de00, subscriber=0x1edea190) subscribe:] + 1300 at RACSignal.m:388 
frame #37: 0x000f74ec Upcoming`-[RACSignal(self=0x2019a790, _cmd=0x0012f167, nextBlock=0x2fdc1ee4, errorBlock=0x2fdc1ec8, completedBlock=0x2fdc1ea8) subscribeNext:error:completed:] + 1124 at RACSignal.m:419 
frame #38: 0x000f3528 Upcoming`__29-[RACSignal(.block_descriptor=0x200f3fe0, signal=0x2019a790) bind:]_block_invoke154 + 636 at RACSignal.m:230 
frame #39: 0x000f3a22 Upcoming`__29-[RACSignal(.block_descriptor=0x200f4130, x=0x200365e0) bind:]_block_invoke178 + 102 at RACSignal.m:246 
frame #40: 0x000ffbb6 Upcoming`-[RACSubscriber sendNext:](self=0x200f4050, _cmd=0x00124ec2, value=0x200365e0) + 294 at RACSubscriber.m:69 
frame #41: 0x000f3694 Upcoming`__29-[RACSignal(.block_descriptor=0x1ed08f40, x=0x200365e0) bind:]_block_invoke_2157 + 76 at RACSignal.m:222 
frame #42: 0x000ffbb6 Upcoming`-[RACSubscriber sendNext:](self=0x1ed077b0, _cmd=0x00124ec2, value=0x200365e0) + 294 at RACSubscriber.m:69 
frame #43: 0x000f2746 Upcoming`__31+[RACSignal(.block_descriptor=0x202adf90, subscriber=0x1ed077b0) return:]_block_invoke + 106 at RACSignal.m:166 
frame #44: 0x000f6a30 Upcoming`__37-[RACSignal(.block_descriptor=0x2fdc23c0) subscribe:]_block_invoke300 + 80 at RACSignal.m:386 
frame #45: 0x00100aca Upcoming`-[RACSubscriptionScheduler schedule:](self=0x200c0e00, _cmd=0x0012de2e, block=0x2fdc23c0) + 542 at RACSubscriptionScheduler.m:40 
frame #46: 0x000f650c Upcoming`-[RACSignal(self=0x20021f60, _cmd=0x0012de00, subscriber=0x1ed077b0) subscribe:] + 1300 at RACSignal.m:388 
frame #47: 0x000f74ec Upcoming`-[RACSignal(self=0x20021f60, _cmd=0x0012f167, nextBlock=0x2fdc2684, errorBlock=0x2fdc2668, completedBlock=0x2fdc2648) subscribeNext:error:completed:] + 1124 at RACSignal.m:419 
frame #48: 0x000f3528 Upcoming`__29-[RACSignal(.block_descriptor=0x200f48e0, signal=0x20021f60) bind:]_block_invoke154 + 636 at RACSignal.m:230 
frame #49: 0x000f3a22 Upcoming`__29-[RACSignal(.block_descriptor=0x200f4b40, x=0x200134a0) bind:]_block_invoke178 + 102 at RACSignal.m:246 
frame #50: 0x000ffbb6 Upcoming`-[RACSubscriber sendNext:](self=0x200f4950, _cmd=0x00124ec2, value=0x200134a0) + 294 at RACSubscriber.m:69 
frame #51: 0x000b8e98 Upcoming`__86+[NSObject(.block_descriptor=0x200f4db0, target=0x200c2a80, observer=0x200c2a80, change=0x200134a0) rac_signalWithChangesFor:keyPath:options:observer:]_block_invoke_2 + 96 at NSObject+RACPropertySubscribing.m:55 
frame #52: 0x000c8d46 Upcoming`-[RACKVOTrampoline observeValueForKeyPath:ofObject:change:context:](self=0x200f4d90, _cmd=0x359cf919, keyPath=0x200c9340, object=0x200c2a80, change=0x200134a0, context=0x001b4444) + 542 at RACKVOTrampoline.m:97 
frame #53: 0x340095f2 Foundation`NSKVONotify + 34 
frame #54: 0x34007b46 Foundation`-[NSKeyValueObservance observeValueForKeyPath:ofObject:change:context:] + 310 
frame #55: 0x33fa3b84 Foundation`NSKeyValueNotifyObserver + 272 
frame #56: 0x33fa37dc Foundation`NSKeyValueDidChange + 336 
frame #57: 0x33f7dcba Foundation`-[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] + 94 
frame #58: 0x0005a732 Upcoming`-[EKEventManager loadEvents](self=0x200c2a80, _cmd=0x00126d19) + 2834 at EKEventManager.m:216 
frame #59: 0x000591ac Upcoming`-[EKEventManager refresh](self=0x200c2a80, _cmd=0x33e9fe1c) + 64 at EKEventManager.m:82 
frame #60: 0x000590d6 Upcoming`__33-[EKEventManager promptForAccess]_block_invoke_2(.block_descriptor=0x2005d020) + 246 at EKEventManager.m:74 
frame #61: 0x3b829792 libdispatch.dylib`_dispatch_call_block_and_release + 10 
frame #62: 0x3b8295da libdispatch.dylib`_dispatch_client_callout + 22 
frame #63: 0x3b82ce44 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 228 
frame #64: 0x336e81b0 CoreFoundation`__CFRunLoopRun + 1288 
frame #65: 0x3365b23c CoreFoundation`CFRunLoopRunSpecific + 356 
frame #66: 0x3365b0c8 CoreFoundation`CFRunLoopRunInMode + 104 
frame #67: 0x3723a33a GraphicsServices`GSEventRunModal + 74 
frame #68: 0x355772b8 UIKit`UIApplicationMain + 1120 
frame #69: 0x0003e074 Upcoming`main(argc=1, argv=0x2fdc3d20) + 116 at main.m:15 
frame #70: 0x3b83cb20 libdyld.dylib`start + 4 

回答

1

問題原來是,我重置商店後,堅持引用EventKit對象。當商店被重置時,這些對象變成「無效」,我猜這意味着它們變成了懸掛指針(真棒)。當第一個鍵因第二個信號的最新值無效而改變時,combineLatest:reduce:失敗。在重置商店之前發送nil兩個信號似乎已經奏效。

-(void)promptForAccess { 
    [_store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) { 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self willChangeValueForKey:EKEventManagerAccessibleKeyPath]; 
      _accessible = granted; 
      [self didChangeValueForKey:EKEventManagerAccessibleKeyPath]; 

      if (_accessible) { 
       // need to set these to nil before resetting the store. 
       [self willChangeValueForKey:EKEventManagerEventsKeyPath]; 
       _events = nil; 
       [self didChangeValueForKey:EKEventManagerEventsKeyPath]; 
       [self willChangeValueForKey:EKEventManagerNextEventKeyPath]; 
       _nextEvent = nil; 
       [self didChangeValueForKey:EKEventManagerNextEventKeyPath]; 

       // load events 
       [_store reset]; 
       [self refresh]; 
      } 
     }); 
    }]; 
} 
相關問題