本文将带您了解关于DispatchSourceTimer和Swift3.0的新内容,另外,我们还将为您提供关于com.google.android.exoplayer2.source.Adaptive
本文将带您了解关于DispatchSourceTimer和Swift 3.0的新内容,另外,我们还将为您提供关于com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener.EventDispatcher的实例源码、Dispatch Source Timer的使用及注意事项介绍、dispatcher Swift、DispatcherTimer和Timer的区别的实用信息。
本文目录一览:- DispatchSourceTimer和Swift 3.0
- com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener.EventDispatcher的实例源码
- Dispatch Source Timer的使用及注意事项介绍
- dispatcher Swift
- DispatcherTimer和Timer的区别
DispatchSourceTimer和Swift 3.0
我不知道如何使调度计时器在Swift 3.0中重复工作。我的代码:
let queue = DispatchQueue(label: "com.firm.app.timer", attributes: DispatchQueue.Attributes.concurrent)let timer = DispatchSource.makeTimerSource(flags: DispatchSource.TimerFlags(rawValue: UInt(0)), queue: queue)timer.scheduleRepeating(deadline: DispatchTime.now(), interval: .seconds(5), leeway: .seconds(1))timer.setEventHandler(handler: { //a bunch of code here})timer.resume()
计时器只会触发一次,不会像应有的那样重复自身。我怎样才能解决这个问题?
答案1
小编典典确保计时器不超出范围。与Timer
(RunLoop
在其计划表上保留强引用直到Timer
无效)不同,您需要维护自己对GCD计时器的强引用,例如:
var timer: DispatchSourceTimer?private func startTimer() { let queue = DispatchQueue(label: "com.firm.app.timer", attributes: .concurrent) timer?.cancel() // cancel previous timer if any timer = DispatchSource.makeTimerSource(queue: queue) timer?.schedule(deadline: .now(), repeating: .seconds(5), leeway: .milliseconds(100)) // or, in Swift 3: // // timer?.scheduleRepeating(deadline: .now(), interval: .seconds(5), leeway: .seconds(1)) timer?.setEventHandler { [weak self] in // `[weak self]` only needed if you reference `self` in this closure and you want to prevent strong reference cycle print(Date()) } timer?.resume()}private func stopTimer() { timer?.cancel() timer = nil}
com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener.EventDispatcher的实例源码
/** * @param trackType The type of the track. One of the {@link C} {@code TRACK_TYPE_*} constants. * @param callback A callback for the wrapper. * @param chunkSource A {@link HlsChunkSource} from which chunks to load are obtained. * @param allocator An {@link Allocator} from which to obtain media buffer allocations. * @param positionUs The position from which to start loading media. * @param muxedAudioFormat Optional muxed audio {@link Format} as defined by the master playlist. * @param minLoadableRetryCount The minimum number of times that the source should retry a load * before propagating an error. * @param eventdispatcher A dispatcher to notify of events. */ public HlsSampleStreamWrapper(int trackType,Callback callback,HlsChunkSource chunkSource,Allocator allocator,long positionUs,Format muxedAudioFormat,int minLoadableRetryCount,Eventdispatcher eventdispatcher) { this.trackType = trackType; this.callback = callback; this.chunkSource = chunkSource; this.allocator = allocator; this.muxedAudioFormat = muxedAudioFormat; this.minLoadableRetryCount = minLoadableRetryCount; this.eventdispatcher = eventdispatcher; loader = new Loader("Loader:HlsSampleStreamWrapper"); nextChunkHolder = new HlsChunkSource.HlsChunkHolder(); sampleQueues = new SparseArray<>(); mediaChunks = new LinkedList<>(); maybeFinishPrepareRunnable = new Runnable() { @Override public void run() { maybeFinishPrepare(); } }; handler = new Handler(); lastSeekPositionUs = positionUs; pendingResetPositionUs = positionUs; }
/** * @param trackType The type of the track. One of the {@link C} {@code TRACK_TYPE_*} constants. * @param callback A callback for the wrapper. * @param chunkSource A {@link HlsChunkSource} from which chunks to load are obtained. * @param allocator An {@link Allocator} from which to obtain media buffer allocations. * @param positionUs The position from which to start loading media. * @param muxedAudioFormat Optional muxed audio {@link Format} as defined by the master playlist. * @param minLoadableRetryCount The minimum number of times that the source should retry a load * before propagating an error. * @param eventdispatcher A dispatcher to notify of events. */ public HlsSampleStreamWrapper(int trackType,Eventdispatcher eventdispatcher) { this.trackType = trackType; this.callback = callback; this.chunkSource = chunkSource; this.allocator = allocator; this.muxedAudioFormat = muxedAudioFormat; this.minLoadableRetryCount = minLoadableRetryCount; this.eventdispatcher = eventdispatcher; loader = new Loader("Loader:HlsSampleStreamWrapper"); nextChunkHolder = new HlsChunkSource.HlsChunkHolder(); sampleQueues = new SparseArray<>(); mediaChunks = new LinkedList<>(); maybeFinishPrepareRunnable = new Runnable() { @Override public void run() { maybeFinishPrepare(); } }; handler = new Handler(); lastSeekPositionUs = positionUs; pendingResetPositionUs = positionUs; }
public DashMediaPeriod(int id,DashManifest manifest,int periodindex,DashChunkSource.Factory chunkSourceFactory,Eventdispatcher eventdispatcher,long elapsedRealtimeOffset,LoaderErrorThrower manifestLoaderErrorThrower,Allocator allocator) { this.id = id; this.manifest = manifest; this.periodindex = periodindex; this.chunkSourceFactory = chunkSourceFactory; this.minLoadableRetryCount = minLoadableRetryCount; this.eventdispatcher = eventdispatcher; this.elapsedRealtimeOffset = elapsedRealtimeOffset; this.manifestLoaderErrorThrower = manifestLoaderErrorThrower; this.allocator = allocator; sampleStreams = newSampleStreamArray(0); sequenceableLoader = new CompositeSequenceableLoader(sampleStreams); adaptationSets = manifest.getPeriod(periodindex).adaptationSets; Pair<TrackGroupArray,EmbeddedTrackInfo[]> result = buildTrackGroups(adaptationSets); trackGroups = result.first; embeddedTrackInfos = result.second; }
private SsMediaSource(SsManifest manifest,Uri manifestUri,DataSource.Factory manifestDataSourceFactory,SsManifestParser manifestParser,SsChunkSource.Factory chunkSourceFactory,long livePresentationDelayMs,Handler eventHandler,AdaptiveMediaSourceEventListener eventListener) { Assertions.checkState(manifest == null || !manifest.isLive); this.manifest = manifest; this.manifestUri = manifestUri == null ? null : Util.toLowerInvariant(manifestUri.getLastPathSegment()).equals("manifest") ? manifestUri : Uri.withAppendedpath(manifestUri,"Manifest"); this.manifestDataSourceFactory = manifestDataSourceFactory; this.manifestParser = manifestParser; this.chunkSourceFactory = chunkSourceFactory; this.minLoadableRetryCount = minLoadableRetryCount; this.livePresentationDelayMs = livePresentationDelayMs; this.eventdispatcher = new Eventdispatcher(eventHandler,eventListener); mediaPeriods = new ArrayList<>(); }
public SsMediaPeriod(SsManifest manifest,Allocator allocator) { this.chunkSourceFactory = chunkSourceFactory; this.manifestLoaderErrorThrower = manifestLoaderErrorThrower; this.minLoadableRetryCount = minLoadableRetryCount; this.eventdispatcher = eventdispatcher; this.allocator = allocator; trackGroups = buildTrackGroups(manifest); ProtectionElement protectionElement = manifest.protectionElement; if (protectionElement != null) { byte[] keyId = getProtectionElementKeyId(protectionElement.data); trackEncryptionBoxes = new TrackEncryptionBox[] { new TrackEncryptionBox(true,INITIALIZATION_VECTOR_SIZE,keyId)}; } else { trackEncryptionBoxes = null; } this.manifest = manifest; sampleStreams = newSampleStreamArray(0); sequenceableLoader = new CompositeSequenceableLoader(sampleStreams); }
public HlsMediaPeriod(Uri manifestUri,DataSource.Factory dataSourceFactory,MediaSource.Listener sourceListener,long positionUs) { this.manifestUri = manifestUri; this.dataSourceFactory = dataSourceFactory; this.minLoadableRetryCount = minLoadableRetryCount; this.eventdispatcher = eventdispatcher; this.sourceListener = sourceListener; this.allocator = allocator; streamWrapperIndices = new IdentityHashMap<>(); timestampAdjusterProvider = new TimestampAdjusterProvider(); manifestParser = new HlsPlaylistParser(); continueLoadingHandler = new Handler(); manifestFetcher = new Loader("Loader:ManifestFetcher"); preparePositionUs = positionUs; continueLoadingRunnable = new Runnable() { @Override public void run() { callback.onContinueLoadingRequested(HlsMediaPeriod.this); } }; }
/** * @param trackType The type of the track. One of the {@link C} {@code TRACK_TYPE_*} constants. * @param callback A callback for the wrapper. * @param chunkSource A {@link HlsChunkSource} from which chunks to load are obtained. * @param allocator An {@link Allocator} from which to obtain media buffer allocations. * @param positionUs The position from which to start loading media. * @param muxedAudioFormat If HLS master playlist indicates that the stream contains muxed audio,* this is the audio {@link Format} as defined by the playlist. * @param muxedCaptionFormat If HLS master playlist indicates that the stream contains muxed * captions,this is the audio {@link Format} as defined by the playlist. * @param minLoadableRetryCount The minimum number of times that the source should retry a load * before propagating an error. * @param eventdispatcher A dispatcher to notify of events. */ public HlsSampleStreamWrapper(int trackType,Format muxedCaptionFormat,Eventdispatcher eventdispatcher) { this.trackType = trackType; this.callback = callback; this.chunkSource = chunkSource; this.allocator = allocator; this.muxedAudioFormat = muxedAudioFormat; this.muxedCaptionFormat = muxedCaptionFormat; this.minLoadableRetryCount = minLoadableRetryCount; this.eventdispatcher = eventdispatcher; loader = new Loader("Loader:HlsSampleStreamWrapper"); nextChunkHolder = new HlsChunkSource.HlsChunkHolder(); sampleQueues = new SparseArray<>(); mediaChunks = new LinkedList<>(); maybeFinishPrepareRunnable = new Runnable() { @Override public void run() { maybeFinishPrepare(); } }; handler = new Handler(); lastSeekPositionUs = positionUs; pendingResetPositionUs = positionUs; }
/** * @param trackType The type of the track. One of the {@link C} {@code TRACK_TYPE_*} constants. * @param chunkSource A {@link ChunkSource} from which chunks to load are obtained. * @param callback An {@link Callback} for the stream. * @param allocator An {@link Allocator} from which allocations can be obtained. * @param positionUs The position from which to start loading media. * @param minLoadableRetryCount The minimum number of times that the source should retry a load * before propagating an error. * @param eventdispatcher A dispatcher to notify of events. */ public ChunkSampleStream(int trackType,T chunkSource,SequenceableLoader.Callback<ChunkSampleStream<T>> callback,Eventdispatcher eventdispatcher) { this.trackType = trackType; this.chunkSource = chunkSource; this.callback = callback; this.eventdispatcher = eventdispatcher; this.minLoadableRetryCount = minLoadableRetryCount; loader = new Loader("Loader:ChunkSampleStream"); nextChunkHolder = new ChunkHolder(); mediaChunks = new LinkedList<>(); readOnlyMediaChunks = Collections.unmodifiableList(mediaChunks); sampleQueue = new DefaultTrackOutput(allocator); lastSeekPositionUs = positionUs; pendingResetPositionUs = positionUs; }
public DashMediaPeriod(int id,int index,Allocator allocator) { this.id = id; this.manifest = manifest; this.index = index; this.chunkSourceFactory = chunkSourceFactory; this.minLoadableRetryCount = minLoadableRetryCount; this.eventdispatcher = eventdispatcher; this.elapsedRealtimeOffset = elapsedRealtimeOffset; this.manifestLoaderErrorThrower = manifestLoaderErrorThrower; this.allocator = allocator; sampleStreams = newSampleStreamArray(0); sequenceableLoader = new CompositeSequenceableLoader(sampleStreams); period = manifest.getPeriod(index); trackGroups = buildTrackGroups(period); }
public SsMediaPeriod(SsManifest manifest,keyId)}; } else { trackEncryptionBoxes = null; } this.manifest = manifest; sampleStreams = newSampleStreamArray(0); sequenceableLoader = new CompositeSequenceableLoader(sampleStreams); }
/** * @param initialPlaylistUri Uri for the initial playlist of the stream. Can refer a media * playlist or a master playlist. * @param dataSourceFactory A factory for {@link DataSource} instances. * @param eventdispatcher A dispatcher to notify of events. * @param minRetryCount The minimum number of times the load must be retried before blacklisting a * playlist. * @param primaryPlaylistListener A callback for the primary playlist change events. */ public HlsPlaylistTracker(Uri initialPlaylistUri,HlsDataSourceFactory dataSourceFactory,int minRetryCount,PrimaryPlaylistListener primaryPlaylistListener) { this.initialPlaylistUri = initialPlaylistUri; this.dataSourceFactory = dataSourceFactory; this.eventdispatcher = eventdispatcher; this.minRetryCount = minRetryCount; this.primaryPlaylistListener = primaryPlaylistListener; listeners = new ArrayList<>(); initialPlaylistLoader = new Loader("HlsPlaylistTracker:MasterPlaylist"); playlistParser = new HlsPlaylistParser(); playlistBundles = new IdentityHashMap<>(); playlistRefreshHandler = new Handler(); }
public HlsMediaSource(Uri manifestUri,AdaptiveMediaSourceEventListener eventListener) { this.manifestUri = manifestUri; this.dataSourceFactory = dataSourceFactory; this.minLoadableRetryCount = minLoadableRetryCount; eventdispatcher = new Eventdispatcher(eventHandler,eventListener); }
public HlsMediaPeriod(HlsPlaylistTracker playlistTracker,long positionUs) { this.playlistTracker = playlistTracker; this.dataSourceFactory = dataSourceFactory; this.minLoadableRetryCount = minLoadableRetryCount; this.eventdispatcher = eventdispatcher; this.allocator = allocator; streamWrapperIndices = new IdentityHashMap<>(); timestampAdjusterProvider = new TimestampAdjusterProvider(); continueLoadingHandler = new Handler(); preparePositionUs = positionUs; }
/** * @param primaryTrackType The type of the primary track. One of the {@link C} * {@code TRACK_TYPE_*} constants. * @param embeddedTrackTypes The types of any embedded tracks,or null. * @param chunkSource A {@link ChunkSource} from which chunks to load are obtained. * @param callback An {@link Callback} for the stream. * @param allocator An {@link Allocator} from which allocations can be obtained. * @param positionUs The position from which to start loading media. * @param minLoadableRetryCount The minimum number of times that the source should retry a load * before propagating an error. * @param eventdispatcher A dispatcher to notify of events. */ public ChunkSampleStream(int primaryTrackType,int[] embeddedTrackTypes,Callback<ChunkSampleStream<T>> callback,Eventdispatcher eventdispatcher) { this.primaryTrackType = primaryTrackType; this.embeddedTrackTypes = embeddedTrackTypes; this.chunkSource = chunkSource; this.callback = callback; this.eventdispatcher = eventdispatcher; this.minLoadableRetryCount = minLoadableRetryCount; loader = new Loader("Loader:ChunkSampleStream"); nextChunkHolder = new ChunkHolder(); mediaChunks = new LinkedList<>(); readOnlyMediaChunks = Collections.unmodifiableList(mediaChunks); int embeddedTrackCount = embeddedTrackTypes == null ? 0 : embeddedTrackTypes.length; embeddedSampleQueues = new DefaultTrackOutput[embeddedTrackCount]; embeddedTracksSelected = new boolean[embeddedTrackCount]; int[] trackTypes = new int[1 + embeddedTrackCount]; DefaultTrackOutput[] sampleQueues = new DefaultTrackOutput[1 + embeddedTrackCount]; primarySampleQueue = new DefaultTrackOutput(allocator); trackTypes[0] = primaryTrackType; sampleQueues[0] = primarySampleQueue; for (int i = 0; i < embeddedTrackCount; i++) { DefaultTrackOutput trackOutput = new DefaultTrackOutput(allocator); embeddedSampleQueues[i] = trackOutput; sampleQueues[i + 1] = trackOutput; trackTypes[i + 1] = embeddedTrackTypes[i]; } mediaChunkOutput = new BaseMediaChunkOutput(trackTypes,sampleQueues); pendingResetPositionUs = positionUs; lastSeekPositionUs = positionUs; }
/** * @param initialPlaylistUri Uri for the initial playlist of the stream. Can refer a media * playlist or a master playlist. * @param dataSourceFactory A factory for {@link DataSource} instances. * @param eventdispatcher A dispatcher to notify of events. * @param minRetryCount The minimum number of times the load must be retried before blacklisting a * playlist. * @param primaryPlaylistListener A callback for the primary playlist change events. */ public HlsPlaylistTracker(Uri initialPlaylistUri,PrimaryPlaylistListener primaryPlaylistListener) { this.initialPlaylistUri = initialPlaylistUri; this.dataSourceFactory = dataSourceFactory; this.eventdispatcher = eventdispatcher; this.minRetryCount = minRetryCount; this.primaryPlaylistListener = primaryPlaylistListener; listeners = new ArrayList<>(); initialPlaylistLoader = new Loader("HlsPlaylistTracker:MasterPlaylist"); playlistParser = new HlsPlaylistParser(); playlistBundles = new IdentityHashMap<>(); playlistRefreshHandler = new Handler(); }
public HlsMediaSource(Uri manifestUri,eventListener); }
public HlsMediaPeriod(HlsPlaylistTracker playlistTracker,long positionUs) { this.playlistTracker = playlistTracker; this.dataSourceFactory = dataSourceFactory; this.minLoadableRetryCount = minLoadableRetryCount; this.eventdispatcher = eventdispatcher; this.allocator = allocator; streamWrapperIndices = new IdentityHashMap<>(); timestampAdjusterProvider = new TimestampAdjusterProvider(); continueLoadingHandler = new Handler(); preparePositionUs = positionUs; }
/** * @param primaryTrackType The type of the primary track. One of the {@link C} * {@code TRACK_TYPE_*} constants. * @param embeddedTrackTypes The types of any embedded tracks,sampleQueues); pendingResetPositionUs = positionUs; lastSeekPositionUs = positionUs; }
private DashMediaSource(DashManifest manifest,DashManifestParser manifestParser,AdaptiveMediaSourceEventListener eventListener) { this.manifest = manifest; this.manifestUri = manifestUri; this.manifestDataSourceFactory = manifestDataSourceFactory; this.manifestParser = manifestParser; this.chunkSourceFactory = chunkSourceFactory; this.minLoadableRetryCount = minLoadableRetryCount; this.livePresentationDelayMs = livePresentationDelayMs; sideloadedManifest = manifest != null; eventdispatcher = new Eventdispatcher(eventHandler,eventListener); manifestUriLock = new Object(); periodsById = new SparseArray<>(); if (sideloadedManifest) { Assertions.checkState(!manifest.dynamic); manifestCallback = null; refreshManifestRunnable = null; simulateManifestRefreshRunnable = null; } else { manifestCallback = new ManifestCallback(); refreshManifestRunnable = new Runnable() { @Override public void run() { startLoadingManifest(); } }; simulateManifestRefreshRunnable = new Runnable() { @Override public void run() { processManifest(false); } }; } }
@Override public MediaPeriod createPeriod(int periodindex,long positionUs) { Eventdispatcher periodEventdispatcher = eventdispatcher.copyWithMediaTimeOffsetMs( manifest.getPeriod(periodindex).startMs); DashMediaPeriod mediaPeriod = new DashMediaPeriod(firstPeriodId + periodindex,manifest,periodindex,chunkSourceFactory,minLoadableRetryCount,periodEventdispatcher,elapsedRealtimeOffsetMs,loaderErrorThrower,allocator); periodsById.put(mediaPeriod.id,mediaPeriod); return mediaPeriod; }
public HlsMediaSource(Uri manifestUri,eventListener); }
public DashMediaSource(Uri manifestUri,AdaptiveMediaSourceEventListener eventListener) { this.manifestUri = manifestUri; this.manifestDataSourceFactory = manifestDataSourceFactory; this.chunkSourceFactory = chunkSourceFactory; this.minLoadableRetryCount = minLoadableRetryCount; this.livePresentationDelayMs = livePresentationDelayMs; eventdispatcher = new Eventdispatcher(eventHandler,eventListener); manifestParser = new DashManifestParser(generateContentId()); manifestCallback = new ManifestCallback(); manifestUriLock = new Object(); periodsById = new SparseArray<>(); refreshManifestRunnable = new Runnable() { @Override public void run() { startLoadingManifest(); } }; simulateManifestRefreshRunnable = new Runnable() { @Override public void run() { processManifest(); } }; }
public SsMediaSource(Uri manifestUri,AdaptiveMediaSourceEventListener eventListener) { this.manifestUri = Util.toLowerInvariant(manifestUri.getLastPathSegment()).equals("manifest") ? manifestUri : Uri.withAppendedpath(manifestUri,"Manifest"); this.dataSourceFactory = dataSourceFactory; this.chunkSourceFactory = chunkSourceFactory; this.minLoadableRetryCount = minLoadableRetryCount; this.livePresentationDelayMs = livePresentationDelayMs; this.eventdispatcher = new Eventdispatcher(eventHandler,eventListener); manifestParser = new SsManifestParser(); mediaPeriods = new ArrayList<>(); }
Dispatch Source Timer的使用及注意事项介绍
前言
Dispatch Source Timer 是一种与 Dispatch Queue 结合使用的定时器。当需要在后台 queue 中定期执行任务的时候,使用 Dispatch Source Timer 要比使用 NSTimer 更加自然,也更加高效(无需在 main queue 和后台 queue 之前切换)。下面将详细给大家介绍关于Dispatch Source Timer的使用和一些注意事项,话不多说了,来一起看看详细的介绍吧。
创建 Timer
Dispatch Source Timer 首先其实是 Dispatch Source 的一种,关于 Dispatch Source 的内容在这里就不再赘述了。下面是苹果官方文档里给出的创建 Dispatch Timer 的代码:
dispatch_source_t CreateDispatchTimer(uint64_t interval, uint64_t leeway, dispatch_queue_t queue, dispatch_block_t block) { dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); if (timer) { dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), interval, leeway); dispatch_source_set_event_handler(timer, block); dispatch_resume(timer); } return timer; }
有几个地方需要注意:
- Dispatch Source Timer 是间隔定时器,也就是说每隔一段时间间隔定时器就会触发。在 NSTimer 中要做到同样的效果需要手动把 repeats 设置为 YES。
- dispatch_source_set_timer 中第二个参数,当我们使用dispatch_time 或者 DISPATCH_TIME_NOW 时,系统会使用默认时钟来进行计时。然而当系统休眠的时候,默认时钟是不走的,也就会导致计时器停止。使用 dispatch_walltime 可以让计时器按照真实时间间隔进行计时。
- dispatch_source_set_timer 的第四个参数 leeway 指的是一个期望的容忍时间,将它设置为 1 秒,意味着系统有可能在定时器时间到达的前 1 秒或者后 1 秒才真正触发定时器。在调用时推荐设置一个合理的 leeway 值。需要注意,就算指定 leeway 值为 0,系统也无法保证完全精确的触发时间,只是会尽可能满足这个需求。
- event handler block 中的代码会在指定的 queue 中执行。当 queue 是后台线程的时候,dispatch timer 相比 NSTimer 就好操作一些了。因为 NSTimer 是需要 Runloop 支持的,如果要在后台 dispatch queue 中使用,则需要手动添加 Runloop。使用 dispatch timer 就简单很多了。
- dispatch_source_set_event_handler 这个函数在执行完之后,block 会立马执行一遍,后面隔一定时间间隔再执行一次。而 NSTimer 第一次执行是到计时器触发之后。这也是和 NSTimer 之间的一个显著区别。
停止 Timer
停止 Dispatch Timer 有两种方法,一种是使用 dispatch_suspend,另外一种是使用 dispatch_source_cancel。
dispatch_suspend 严格上只是把 Timer 暂时挂起,它和 dispatch_resume 是一个平衡调用,两者分别会减少和增加 dispatch 对象的挂起计数。当这个计数大于 0 的时候,Timer 就会执行。在挂起期间,产生的事件会积累起来,等到 resume 的时候会融合为一个事件发送。
需要注意的是:dispatch source 并没有提供用于检测 source 本身的挂起计数的 API,也就是说外部不能得知一个 source 当前是不是挂起状态,在设计代码逻辑时需要考虑到这一点。
dispatch_source_cancel 则是真正意义上的取消 Timer。被取消之后如果想再次执行 Timer,只能重新创建新的 Timer。这个过程类似于对 NSTimer 执行 invalidate。
关于取消 Timer,另外一个很重要的注意事项:dispatch_suspend 之后的 Timer,是不能被释放的!下面的代码会引起崩溃:
- (void)stopTimer { dispatch_suspend(_timer); _timer = nil; // EXC_BAD_INSTRUCTION 崩溃 }
因此使用 dispatch_suspend 时,Timer 本身的实例需要一直保持。使用 dispatch_source_cancel 则没有这个限制:
- (void)stopTimer { dispatch_source_cancel(_timer); _timer = nil; // OK }
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
dispatcher Swift
dispatcher Swift 介绍
dispatcher 是用 Swift 编写的,包括队列,计时器和任务组等功能。
dispatcher Swift 官网
https://github.com/aleclarson/dispatcher
DispatcherTimer和Timer的区别
两者区别是 Timer在非UI线程跑的,DispatcherTimer是在UI线程跑的,
DispatcherTimer 可以直接更新UI
private void DisPatcherTimerMethod()
今天关于DispatchSourceTimer和Swift 3.0的讲解已经结束,谢谢您的阅读,如果想了解更多关于com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener.EventDispatcher的实例源码、Dispatch Source Timer的使用及注意事项介绍、dispatcher Swift、DispatcherTimer和Timer的区别的相关知识,请在本站搜索。
本文标签: