The questions are from here, and I have answered the questions about knowledge and experience. I hope you can fill in the answers if you missed them. This is the interview question you can use.

How does Push Notification work?

  • Push notifications are divided into two types, one is local push, the other is remote push
    • Local push: it can also be pushed without networking. The developer sets a specific time in the APP to remind the user what to do
    • Remote push: To connect to the Internet, the user’s device will form a long connection with the Apple APNS server, and the user’s device will send uUID and Bundle Idenidentifier to the Apple server, the Apple server will encrypt and generate a deviceToken to the user device, and then the device will send deviceToken to the APP’s server, and the server will store deviceToken in their database, and at this point if someone sends a message to me, the server The end will query my deviceToken, and then send the deviceToken and the information to be sent to the Apple server. The Apple server will find my device through deviceToken and push the message to my device. Another case here is that if the APP is online, the APP server will generate one for the APP In this case, the APPF server pushes messages to the device directly through deviceToken

What is Runloop?

Is a thread-specific mechanism that can be understood as a loop in which events are waited for and then processed. In Cocoa, every thread has its runroop. By this mechanism, threads can rest when there are no events to be processed. Events can be run to relieve CPU stress

What is Toll-free Bridging? When will it be used?

Toll-free Bridging is used to exchange data between Foundation objects and Core Foundation objects, commonly known as Bridging

  • In the ARC environment,Foundation objects become Core Foundation objects
    • use__bridgeAfter the bridge ARC will automatically two objects
    • use__bridge_retainedBridging requires manual release of Core Foundation objects
  • In the ARC environment, Core Foundation objects become Foundation objects
    • use__bridgeBridge, if Core Foundation objects are released,Foundation objects are also unusable, and you need to manually manage Core Foundation objects
    • use__bridge_transferBridge, the system automatically manages two objects

What happens when the system gets a memory warning?

  • Temporarily removes views that are not on the current window
  • If memory warnings are left unchecked, software can eventually be forced to shut down by the system

What’s a Protocol? What’s a Delegate?

  • A protocol is a list of method signatures in which several methods can be defined. Classes that comply with the protocol can implement the methods in the protocol and use them in the protocol@propertyOnly declarations of setter and getter methods are generated
  • Delegate: Acts as a delegate for a class that implements methods in the protocol

Under what circumstances will an AutoRelease object be released?

  • There are two cases: manual intervention release and system automatic release
    • Manual intervention release is to specify an AutoReleasepool that is released as soon as the current scope braces end
    • System automatically to release: no manually specify autoreleasepool, Autorelease objects will be released at the end of the current runloop iteration
      • KCFRunLoopEntry (1): An autoRelease is automatically created on the first entry
      • KCFRunLoopBeforeWaiting (32): An AutoRelease is destroyed before hibernation and a new autoRelease is created
      • KCFRunLoopExit (128): The last autorelease created is automatically destroyed when exiting the runloop

Why is NotificationCenter removeObserver? How to implement automatic remove?

  • If not removed, the program will crash in case notifications are sent after the class that registered them is destroyed. Because a message was sent to the wild pointer
  • Automatic remove: Through the self-release mechanism, remove is transferred to a third party through dynamic properties, and the coupling is removed to achieve automatic remove

When the TableView Cell changes, how do I animate those changes?

For example, click on the cell and animate it to change its height

@interface ViewController () @property (nonatomic, strong) NSIndexPath *index; @end @implementation ViewController static NSString *ID = @"cell"; - (void)viewDidLoad { [super viewDidLoad]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; cell.textLabel.text = [NSString stringWithFormat:@"%ld",(long)indexPath.row]; return cell; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 20; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if(self.index == indexPath){ return 120; } return 60; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { self.index = indexPath; [tableView deselectRowAtIndexPath:indexPath animated:TRUE]; // Focus on the function of this 2 sentences [tableView beginUpdates]; [tableView endUpdates]; }Copy the code

Why does UIScrollView scrolling cause NSTimer to fail?

There is a runoop mode in the timer, normally the timer is running on defaultMode, but if you slide the page, the main runloop will go to UITrackingRunLoopMode, and the timer will not be able to process, causing the timer to fail, and the reason is runroop The default mode is nsRunLoopCommonMode. The default mode is nsRunLoopCommonMode. The default mode is nsRunLoopCommonMode, and the default mode is nsRunLoopCommonMode

Why does the layer revert to its original state when the Core Animation completes?

Because these generated animations are just an illusion and do not change the layer. So why does that happen? Here’s a little bit about rendering trees in layer trees. The rendering tree is actually a copy of the model layer, but its property values represent the current appearance. The animation actually changes the rendering tree, not the layer properties, so the layer will revert to its original state after the animation is over

How do you store sensitive information about users, such as login tokens

  • A keychain is used to store keys. To use a keychain, you need to import keysSecurityThe framework

User-defined a keychain class

#import @implementation YCKKeyChain + (NSMutableDictionary *)getKeychainQuery:(NSString *)service { return [NSMutableDictionary dictionaryWithObjectsAndKeys: (__bridge_transfer id)kSecClassGenericPassword,(__bridge_transfer id)kSecClass, service, (__bridge_transfer id)kSecAttrService, service, (__bridge_transfer id)kSecAttrAccount, (__bridge_transfer id)kSecAttrAccessibleAfterFirstUnlock,(__bridge_transfer id)kSecAttrAccessible, nil]; } + (void)save:(NSString *)service data:(id)data {// get the search dictionary NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; // Add new delete old SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery); / / add a new object to a string [keychainQuery setObject: [NSKeyedArchiver archivedDataWithRootObject: data] forKey: (__bridge_transfer id)kSecValueData]; // query key string SecItemAdd((__bridge_retained CFDictionaryRef)keychainQuery, NULL); } + (id)load:(NSString *)service { id ret = nil; NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; // configure search Settings [keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge_transfer id)kSecReturnData]; [keychainQuery setObject:(__bridge_transfer id)kSecMatchLimitOne forKey:(__bridge_transfer id)kSecMatchLimit]; CFDataRef keyData = NULL; if (SecItemCopyMatching((__bridge_retained CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) { @try { ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge_transfer NSData *)keyData]; } @catch (NSException *e) { NSLog(@"Unarchive of %@ failed: %@", service, e); } @finally { } } return ret; } + (void)delete:(NSString *)service { NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery); }Copy the code

In other classes to store, load, delete sensitive information methods

Static NSString * const KEY_IN_KEYCHAIN = @" com.ck.app.allinfo "; static NSString * const KEY_IN_KEYCHAIN = @" com.ck.app.allinfo "; Static NSString * const KEY_PASSWORD = @" com.ck. App. password"; static NSString * const KEY_PASSWORD = @" com.ck. + (void)savePassWord:(NSString *)password { NSMutableDictionary *passwordDict = [NSMutableDictionary dictionary]; [passwordDict setObject:password forKey:KEY_PASSWORD]; [YCKKeyChain save:KEY_IN_KEYCHAIN data:passwordDict]; } + (id)readPassWord { NSMutableDictionary *passwordDict = (NSMutableDictionary *)[YCKKeyChain load:KEY_IN_KEYCHAIN]; return [passwordDict objectForKey:KEY_PASSWORD]; } + (void)deletePassWord { [YCKKeyChain delete:KEY_IN_KEYCHAIN]; }Copy the code

Have you used some open source components? Can you briefly talk about a few of them and the implementation of their usage scenarios?

  • AFN: network request
  • FMDB: Use the database
  • MJExtension: JSON interflows with Model
  • SVProgressHUD: prompt HUD
  • Navigation: automatic layout
  • MJRefresh: Pull down and pull up refresh

When does an EXC BAD ACCESS exception occur?

  • Access a zombie object, access its member variables, or send a message to it
  • Infinite loop

What are the usage scenarios of NSNotification and KVO?

  • KVO usage scenario: When one or more objects need to be notified when a specific property of an object changes
  • NSNotification usage scenario: Transfer values across hierarchies and multiple objects notify multiple objects

What should I pay attention to when using blocks?

  • Used when an external pointer is used inside a block and creates a circular reference__weakDecorates the external pointer

    __weak typeof(self) weakSelf = self;
  • If you call a delay function inside the block and use a weak pointer, you will not get the pointer because it has been destroyed, so you need to re-reference the weak pointer inside the block__strong typeof(self) strongSelf = weakSelf;
  • If you need to change an external variable inside a block, you need to__blockModify external variables

    I also wrote oneblockblog

PerformSelector: withObject: afterDelay: internal is about how to implement, what’s the matters needing attention?

  • You create a timer, and when the time is up the system uses runtime to find the corresponding method implementation in the list of methods by Selector name and call that method
  • Matters needing attention
    • callperformSelector:withObject:afterDelay:Method, first determine whether the method you want to call existsrespondsToSelector:
    • This method is asynchronous and must be called in the main thread. Calls in child threads never call the desired method

How do I deal with Boolean defaults when USING NSUserDefaults? (for example, return NO, whether it is true or not set)

If ([[NSUserDefaults standardUserDefaults] objectForKey:ID] == nil){NSLog(@" not set "); }Copy the code

What are some ways to slim down a ViewController?

  • Separate the Data Source from other Protocols (extract the code from UITableView or UICollectionView and put it in another class)
  • Move business logic to Model (all model-related logic is written in Model)
  • Move network request logic to Model layer (network request depends on Model)
  • Move the View code to the View layer (custom View)

What are some common Crash scenarios?

  • A zombie object was accessed
  • A method that does not exist was accessed
  • An array
  • When the timer is released before the next callback, Crash occurs