iOS面试题收纳-其他

100 阅读2分钟

多列表多计时器问题怎么解决

使用一个定时器,内部弱引用保存N多需要使用定时器的类

NS_ASSUME_NONNULL_BEGIN
@class TimerService;
//监听者需要实现的协议
@protocol TimerListener <NSObject>
@required
- (void)didOnTimer:(TimerService *)timer;
@end

@interface TimerService : NSObject
//对接提供的主要接口
+ (instancetype)sharedInstance;

- (void)startTimer;
- (void)stopTimer;

- (void)addListener:(id<TimerListener>)listener;
- (void)removeListener:(id<TimerListener>)listener;
@end

NS_ASSUME_NONNULL_END


@interface TimerService() {
    NSLock  *_operationLock;
    NSUInteger _elapseSeconds;
}
@property (nonatomic, strong) NSHashTable       *listeners;

@property (nonatomic, assign) NSTimeInterval    timeInterval;
@property (nonatomic, assign) NSTimeInterval    tolerance;
@property (nonatomic, strong) dispatch_queue_t  privateSerialQueue;
@property (nonatomic, strong) dispatch_source_t timer;
@end

@implementation TimerService

+ (instancetype)sharedInstance {
    static TimerService *timerService = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        timerService = [[TimerService alloc] init];
        [timerService setup];
    });
    return timerService;
}

- (void)dealloc {
    [self stopTimer];
}

- (void)setup {
    _operationLock = [[NSLock alloc] init];
    _listeners = [NSHashTable weakObjectsHashTable];
    
    _elapseSeconds = 0;
    _timeInterval = 1.f;
    _tolerance = 0.f;
    NSString *privateQueueName = [NSString stringWithFormat:@"com.zk.timer.%p", self];
    _privateSerialQueue = dispatch_queue_create([privateQueueName cStringUsingEncoding:NSASCIIStringEncoding],
                                                DISPATCH_QUEUE_SERIAL);
}

#pragma mark - public
- (void)addListener:(id<TimerListener>)listener {
    [_operationLock lock];
    if (![self.listeners containsObject:listener]) {
        [self.listeners addObject:listener];
        if(self.listeners.count > 0) {
            //启动
            [self startTimer];
        }
    }
    [_operationLock unlock];
}

- (void)removeListener:(id<TimerListener>)listener {
    [_operationLock lock];
    if ([self.listeners containsObject:listener]) {
        [self.listeners removeObject:listener];
        if(self.listeners.count == 0){
            //暂停
            [self stopTimer];
        }
    }
    [_operationLock unlock];
}

- (void)startTimer {
    _elapseSeconds = 0;
    if (_timer == nil) {
        _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.privateSerialQueue);
        
        int64_t intervalInNanoseconds = (int64_t)(self.timeInterval * NSEC_PER_SEC);
        int64_t toleranceInNanoseconds = (int64_t)(self.tolerance * NSEC_PER_SEC);
        dispatch_source_set_timer(self.timer,
                                  dispatch_time(DISPATCH_TIME_NOW, intervalInNanoseconds),
                                  (uint64_t)intervalInNanoseconds,
                                  toleranceInNanoseconds
                                  );
        
        dispatch_source_set_event_handler(self.timer, ^{
            dispatch_async(dispatch_get_main_queue(), ^{
                [self onTimer];
            });
        });
        dispatch_resume(_timer); // 启动定时器
    }
}

- (void)stopTimer {
    _elapseSeconds = 0;
    if (_timer != nil) {
        dispatch_source_t timer = _timer;
        dispatch_async(_privateSerialQueue, ^{
            dispatch_source_cancel(timer);
        });
        _timer = nil;
    }
}

//定时器回调
- (void)onTimer {
    _elapseSeconds += 1;
    [self.listeners.allObjects enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        id<TimerListener> listener = obj;
        if ([listener respondsToSelector:@selector(didOnTimer:)]) {
            [listener didOnTimer:self];
        }
    }];
}

@end

用过iconfont吗,它的实现原理是什么样的

iconfont是阿里妈妈的一个线上字体设置的库。

主要原理就是通过取出svg里面的path对应的序列,我们自由组合之后,平台会对取出的path做一系列的转换操作,然后合成一个大的path。生成字体

实现原理

pod install与pod update的区别

pod install

  1. 如果Podfile.lock文件存在,则直接从此文件中读取框架信息并且它会只下载Podfile.lock文件中指定的版本安装。
  2. 对于不在Podfile.lock文件中的pod库,pod install命令会搜索这个pod库在Podfile文件中指定的版本来安装;
  3. 如果Podfile.lock不存在, 则会读取Podfile文件内的框架信息,然后执行下载并且根据下载好的框架信息, 生成Podfile.lock文件。

pod update

只有当你想要更新pod库的版本时才使用pod update;

  1. 它不管Podfile.lock是否存在, 都会读取Podfile文件的的框架信息去下载安装,下载好之后, 再根据下载好的框架信息, 生成Podfile.lock文件

BitMap的理解和使用

blog.csdn.net/qq_32924343…

减少项目中的if else 或者switch

juejin.cn/post/699063…

www.jianshu.com/p/0690516e5…