cannot decode object of class (UserAction) for key (userAction) because no class named “UserAction” was found

Even though the class name UserAction in Swift, only putting “@objc” make different className maybe because of mangling

https://stackoverflow.com/a/25599675

If you saved that class using “@objc(UserAction)” before, then you should keep that line to unarchive.

Crash: [NSTaggedPointerString count]: unrecognized selector sent to instance 0x8000000000000000

This occured

    class func weakCollection<T: BaseModel>(with type: T.Type) -> WeakCollection? {
        let classType = String(describing: type)
        let weakCollection = WeakCollections.shared.weakColectionDic[classType] ?? WeakCollection()
        WeakCollections.shared.weakColectionDic[classType] = weakCollection // error occurred
        return weakCollection as? WeakCollection
    }

This line is called when the API request received a data which needs an sync throughout the app. The error occurred when multiple API requests are sent, and

“WeakCollections.shared.weakColectionDic[classType] = weakCollection”

This line is called multiple times. It was thread issue.

I found the answer https://developer.apple.com/forums/thread/682446 here.

So I changed the code to

        if let savedCollection = WeakCollections.shared.weakColectionDic[classType] {
            return savedCollection as? WeakCollection
        } else {
            let weakCollection = WeakCollection()
            WeakCollections.shared.weakColectionDic[classType] = weakCollection
            return weakCollection
        }

this. Making setting value not occurred multiple times. Then the error disappeared.

keyWindow is nil on viewDidAppear crash

if !isKind(of: type(of: UIViewController.current())) { //Crash is here
            return
        }
+ (UIViewController *)currentViewController {
    UIViewController* viewController = [UIApplication sharedApplication].keyWindow.rootViewController; 
    return [UIViewController topViewController:viewController];
}

UIViewController.current() is nil. So crash occurred “Unexpectedly found nil while implicitly unwrapping an Optional… “. It’s because [UIApplication sharedApplication].keyWindow is nil.

But how keyWindow can be nil?

  1. keyWindow is set when “makeKeyAndVisible” is called.
  2. The view controller is entry point view controller of the storyboard.
  3. So it was before “makeKeyAndVisible” is called

But [[[UIApplication sharedApplication] delegate] window] is set at that time. Because it’s “The window to use when presenting a storyboard.”.

->

Removed the line. The check was not needed at the first place.

RemoveObserver before deinit

@implementation UIScrollView (WatchaInfiniteScrolling)

@dynamic infiniteScrollingView;

- (void)addInfiniteScrollingWithActionHandler:(void (^)(void))actionHandler {
    [self addObserver:self.infiniteScrollingView forKeyPath:@"contentInset" options:NSKeyValueObservingOptionNew context:nil];
}

@end

#pragma mark - InfiniteScrollingView
@implementation InfiniteScrollingView

- (void)willMoveToSuperview:(UIView *)newSuperview {
    if (self.superview && newSuperview == nil) {
        [scrollView removeObserver:self forKeyPath:@"contentInset"];
    }
}

@end

https://developer.apple.com/documentation/objectivec/nsobject/1408054-removeobserver?language=objc

I have to removeObserver before deinit. Calling removeObserver before adding makes error.

Calling removeObserver is not needed from iOS 9 -> It’s only subject to NotificationCenter.

https://developer.apple.com/documentation/foundation/notificationcenter/1413994-removeobserver

But in release note of macOS 10.13 and iOS 11 https://developer.apple.com/library/archive/releasenotes/Foundation/RN-Foundation/index.html

Relaxed Key-Value Observing Unregistration Requirements

Prior to 10.13, KVO would throw an exception if any observers were still registered after an autonotifying object’s -dealloc finished running. Additionally, if all observers were removed, but some were removed from another thread during dealloc, the exception would incorrectly still be thrown. This requirement has been relaxed in 10.13, subject to two conditions:

• The object must be using KVO autonotifying, rather than manually calling -will and -didChangeValueForKey: (i.e. it should not return NO from +automaticallyNotifiesObserversForKey:)
• The object must not override the (private) accessors for internal KVO state

If all of these are true, any remaining observers after -dealloc returns will be cleaned up by KVO; this is also somewhat more efficient than repeatedly calling -removeObserver methods.

It says you don’t need to removeObserver before deinit. But this works only from 11.2 and crash occurs in 11.1.

Crashed: WebThread -[UIWebView webView:resource:canAuthenticateAgainstProtectionSpace:forDataSource:] + 92 UIKit on non-main thread

https://developer.apple.com/documentation/uikit/uiwebview/1617937-delegate

Possible cause:

  1. User taps close button
  2. the view release memory
  3. The object set as webView’s delegate also release memory
  4. UIWebView.delegate  (nonatomic, assign). in web thread it accesses web view delegate