
ã¢ãã€ã«ã¢ããªã®ã€ã³ã¿ãŒãã§ã€ã¹ã¯è£œåã®é¡ã§ãã ã€ã³ã¿ãŒãã§ã€ã¹ã®å¿çæ§ãé«ãã»ã©ã補åã®åã³ã¯å€§ãããªããŸãã ãã ããã¢ããªã±ãŒã·ã§ã³ã®äœ¿çšã«å¯Ÿããæºè¶³åºŠã¯ãäž»ã«ãã®æ©èœã®éã«äŸåããŸãã ã¿ã¹ã¯ã®æ°ãšè€éããå¢ãã«ã€ããŠãããå€ãã®æéãå¿ èŠã«ãªããŸãã ã¢ããªã±ãŒã·ã§ã³ã®ã¢ãŒããã¯ãã£ããã¹ãŠãã¡ã€ã³ã¹ã¬ããã§å®è¡ããããšæ³å®ããŠããå Žåãããžãã¹ããžãã¯ã®ã¿ã¹ã¯ã¯ãã€ã³ã¿ãŒãã§ãŒã¹ã®ã¬ã³ããªã³ã°ã¿ã¹ã¯ãšæéã®çµéãšãšãã«ç«¶åãå§ããŸãã ãã®ã¢ãããŒãã§ã¯ãé ããæ©ããã¹ã¯ãªãããå¿ ç¶çã«æ€åºããããã®å®è¡ã¯ã¢ããªã±ãŒã·ã§ã³ã®åºçã«ã€ãªãããŸãã ãã®æšåãšæŠãããã«ã3ã€ã®æ ¹æ¬çã«ç°ãªãã¢ãããŒãããããŸãïŒ
- åé¡ã·ããªãªã®å®è¡ã«é¢ä¿ããã¢ã«ãŽãªãºã ãšããŒã¿æ§é ã®æé©åã
- ã¡ã€ã³ã¹ã¬ããããåé¡ã®ããã·ããªãªãåé€ããŸãã
- å®éã®ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã¬ã³ããªã³ã°ãé€ãããã¹ãŠã®ã¢ããªã±ãŒã·ã§ã³æ©èœã®ã¡ã€ã³ã¹ã¬ããããã®åé€ã
SchedulableObjectãã¿ãŒã³ã䜿çšãããšã3çªç®ã®ã·ããªãªãæ£ç¢ºã«å®è£ ã§ããŸãã ãã³ã®äžã§ã¯ãæåã®2ã€ã®ã¢ãããŒããšæ¯èŒããå Žåã®é·æãšçæã ãã§ãªããSwiftã§ã®å®è£ äŸãå«ããã®éšåãèæ ®ãããŸãã
åé¡ã®å£°æ
1ç§éã«å°ãªããšã60åæŽæ°ã§ãããã®ãããªã€ã³ã¿ãŒãã§ã€ã¹ã¯ã¹ã ãŒãºã§ãããšèŠãªãããŸãã ãããã®å³ã¯ãå察åŽããã衚瀺ã§ããŸãã

åã€ãã³ãåŠçãµã€ã¯ã«ã«ã¯16.7ããªç§ã§å®äºããæéãå¿ èŠã§ããããšãããããŸããã ãŠãŒã¶ãŒã10ããªç§ã§æç»ã§ãããŠã£ã³ããŠãç£èŠãããšããŸãã ã€ãŸãããã¹ãŠã®ããžãã¹ããžãã¯ã¿ã¹ã¯ã¯6.7ããªç§ã§å®äºããå¿ èŠããããŸãã

äŸãšããŠãã¯ã©ãŠãã«ãã¡ã€ã«ãè¿œå ããããžãã¹ããžãã¯ãèããŸãã ããã¯å€ãã®æ®µéã§æ§æãããŠããããã®èšäºã®æèã§ã¯ãã®æ¬è³ªã¯ç§ãã¡ã®èå³ãåŒããã®ã§ã¯ãããŸããã

éèŠãªããšã¯ããããããã¹ãŠäžç·ã«2.6ããªç§ãããããšã§ãã 1ã€ã®ãã¡ã€ã«ãè¿œå ããŠãããžãã¹ããžãã¯ã®äœæ¥ã«å²ãåœãŠãããæ倧æéãåå²ãããšã3ãåŸãããŸãããããã£ãŠããã®ã·ããªãªãå®è¡ãããšãã«ã¢ããªã±ãŒã·ã§ã³ãå¿çæ§ãç¶æãããå ŽåãäžåºŠã«3ã€ä»¥äžã®ãã¡ã€ã«ãè¿œå ããããšã¯ã§ããŸããã ãŠãŒã¶ãŒã«ãšã£ãŠã¯å¹žãã§ãããéçºè ã«ãšã£ãŠã¯æ®å¿µãªããšã«ãäžåºŠã«3ã€ä»¥äžã®ãã¡ã€ã«ãè¿œå ããå¿ èŠãããã¯ã©ãŠãã¢ããªã±ãŒã·ã§ã³ã®å ŽåããããŸãã

äžèšã®ã¹ã¯ãªãŒã³ã·ã§ããã¯ãããã®ããã€ãã瀺ããŠããŸãïŒ
- ããã€ã¹ã®ã·ã¹ãã ã®ã£ã©ãªãŒããã®ãã¡ã€ã«ã®è€æ°éžæã
- ã®ã£ã©ãªãŒããæ°ãããã¡ã€ã«ãèªåçã«ããŠã³ããŒãããŸãã
çŸæç¹ã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã®é·æéã®äžæãé¿ããããã«ãã¹ã¿ãŒãã¢ãããµãŒãã¹ã«ããããŠã³ããŒãã®ããã«ãã¥ãŒã«ãã¡ã€ã«ãè¿œå ããé床ã¯ãæ¥ãã¹ãå®æ°ã®æ¹æ³ã«ãã£ãŠäººçºçã«å¶éãããŠããŸãã 以äžã«ãã®ãã¡ã®2ã€ã瀺ããŸãã
// static uint const kMRCCameraUploaderBatchSize = 1000; static NSTimeInterval const kMRCCameraUploaderBatchDelaySec = 5;
ãããã®ã»ãã³ãã£ã¯ã¹ã¯æ¬¡ã®ãšããã§ããæ°ããåçãã®ã£ã©ãªãŒã§ã¹ãã£ã³ããçµæã«å¿ããŠããµãŒãã¹ã¯ãããã5ç§ééã§1000å以äžã®ãããã§ããŠã³ããŒããã¥ãŒã«è¿œå ããå¿ èŠããããŸãã ãããããã®å¶éããã£ãŠãã5ç§ããšã«1000 * 2.6 ms = 2.6ç§ã®ãã³ã°ãçºçããŸãã ããžãã¹ããžãã¯ã®åž¯åå¹ ã®äººçºçãªå¶éã¯ãSchedulableObjectãã¿ãŒã³ã«æ³šç®ããå¿ èŠãããããšã瀺ããŸãã«ãã®çç¶ã§ãã
SchedulableObjectãšã¢ã«ãŽãªãºã
åé¡ã解決ããããã«ã¢ã«ãŽãªãºã ãšããŒã¿æ§é ãæé©åããåé¡ã解決ããŠã¿ãŸãããïŒ ç§ã¯ãããè¯ãã¢ããªã±ãŒã·ã§ã³ã«å€ããå¿èåã§ããã¹ãŠãæ¬åœã«æªããªã£ããšããã¢ããããŒããã¥ãŒã«åçãè¿œå ããç¹å®ã®æé ãæé©åããŸãã ãã ãããããã®åªåã®å¯èœæ§ã¯æå³çã«å¶éãããŠããŸãã ã¯ããäœããã²ãã£ãŠããã¯ã®ãµã€ãºã2ãã4ååã«å¢ããããšãã§ããŸãããããã¯æ ¹æ¬çã«åé¡ã解決ããŸããã 第äžã«ãæé©åã®ããã«ã¯ããã®å¹æå šäœãæé€ããããŒã¿ã¹ããªãŒã ãå¿ ãååšããŸãã ã¯ã©ãŠãã«é¢é£ããŠãããã¯ã®ã£ã©ãªãŒã«2äžæ以äžã®åçããããŠãŒã¶ãŒã§ãã 第äºã«ã管çè ã¯ééããªãã¹ã¯ãªãããããã«ã€ã³ããªãžã§ã³ãã«ããããšãæã¿ãŸããããã¯å¿ ç¶çã«ããžãã¯ã®è€éåã«ã€ãªãããŸãã以åã«å®è¡ããæé©åãæé©åããå¿ èŠããããŸãã 第äžã«ãã¹ã«ãŒãããã人çºçã«å¶éãããã·ããªãªã¯ããŒãã ãã§ã¯ãããŸããã ããã«ããã¯ãã¢ã«ãŽãªãºã ã§èª¿æŽããã«ã¯ãåã·ããªãªã«åå¥ã®ã¢ãããŒããå¿ èŠã§ãã ããã«æªãããšã«ããããã©ãŒãã³ã¹ãå±æ§ã¯ãç§ã®æèŠã§ã¯ããµããŒãããšåŒã°ããå¥ã®ããéèŠãªã¢ã³ã¿ãŽãã¹ãã§ãã å€ãã®å Žåãå¿ èŠãªããã©ãŒãã³ã¹ãå®çŸããã«ã¯ãã¢ã«ãŽãªãºã ã®ããŸããŸãªããªãã¯ã«é²ãããããè€éãªããŒã¿æ§é ãéžæãããããã®äž¡æ¹ãå¿ èŠã§ãã ã¯ã©ã¹ã®ãããªãã¯ã€ã³ã¿ãŒãã§ã€ã¹ããŸãã¯å°ãªããšããã®å éšå®è£ ã®ãããã«ãããŠãããããã®éžæããã€ãã¹ã«æžéããããšã¯ãããŸããã
å¥ã®ã¹ã¬ããã§ã®SchedulableObjectãšã¹ã¯ãªããã®å²ãåœãŠ
åã·ããªãªãåå¥ã®ã¹ããªãŒã ã«åé¢ããããšã®é©åæ§ã«ã€ããŠç¬èªã®æ±ºå®ãè¡ãã¢ãããŒãã®æ¬ ç¹ãèæ ®ããŠãã ããã ãã®ç®çã®ããã«ãç¹å®ã®ããžãã¹ã¢ããªã±ãŒã·ã§ã³ã®ã¢ãŒããã¯ãã£ã®é²åã远跡ããããã¬ãŒããåé¡ã解決ããããã«ãã®ååã«å°ãããŸãã ããã§ã¯ã¹ã¬ãããç¹ã«èå³æ·±ãããããªããžã§ã¯ãã®ã¡ãœãããåŒã³åºãããã³ã³ããã¹ãã§ã¯ãã¹ã¬ããã¯ããããç¬èªã®è²ã§ãšã³ã³ãŒããããŸãã æåã¯ãéãã·ããªãªããŸã ç»å ŽããŠããªãå Žåããã¹ãŠãã¡ã€ã³ã¹ã¬ããã§çºçããããããã¹ãŠã®æ¥ç¶ãšãšã³ãã£ãã£ã¯åãéè²ã«ãªããŸãã

ãªããžã§ã¯ãã®1ã€ãéåžžã«å€ãã®æéãæ¶è²»ãå§ããã·ããªãªãçŸãããšããŸãã ãã®ããããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®å¿çæ§ãäœäžãå§ããŸãã åé¡ã®ããããŒã¿ãããŒã倪ãç¢å°ã§ç€ºããŸãã

ãªãœãŒã¹ãéäžçã«äœ¿çšããã¯ã©ã¹ããªãã¡ã¯ã¿ãªã³ã°ããªããšãå¥ã®èµ€ãã¹ããªãŒã ã§ãã®ã¯ã©ã¹ãåŒã³åºãããšã¯ã§ããŸããã

ãã®çç±ã¯ãã¯ã©ã€ã¢ã³ãã1ã€ã§ã¯ãªã2ã€ã§ããã2ã€ç®ãã¡ã€ã³ã®éãã¹ã¬ããããåŒã³åºããè¡ã£ãŠããããã§ãã ãããã®åŒã³åºãããªããžã§ã¯ãã®å ±æç¶æ ãå€æŽãããšãããŒã¿ç«¶åã®å€å žçãªåé¡ãçºçããŸãã ããããä¿è·ããã«ã¯ãã¹ã¬ããã»ãŒããªæ¹æ³ã§èµ€ããªããžã§ã¯ããå®è£ ããå¿ èŠããããŸãã

ãããžã§ã¯ããé²è¡ããã«ã€ããŠãå¥ã®ã³ã³ããŒãã³ããããã«ããã¯ã«ãªããŸãã 幞ãã圌ã«ã¯ã¯ã©ã€ã¢ã³ãã1ã€ãããªããã¹ã¬ããã»ãŒããªå®è£ ã¯å¿ èŠãããŸããã§ããã

ãã®ã¢ãããŒãããã«ãã¹ã¬ããã¢ãŒããã¯ãã£ã®èšèšã«å€æ¿ãããšãé ããæ©ãã次ã®ç¶æ ã«ãªããŸãã

å°ãè€éã«ãªããšãããã¯å®å šã«åãããããªããŸãã

ã³ãŒãåThread-Safe Architectureã䜿çšããã¢ãããŒãã®æ¬ ç¹ã¯æ¬¡ã®ãšããã§ãã
- ã¡ãœãããŸãã¯ã¯ã©ã¹ã®ã·ã³ã°ã«ã¹ã¬ããå®è£ ãã¹ã¬ããã»ãŒãã«ïŒããã³ãã®éã«ïŒã¿ã€ã ãªãŒã«ãªãã¡ã¯ã¿ãªã³ã°ããã«ã¯ããªããžã§ã¯ãéã®æ¥ç¶ãåžžã«ç£èŠããå¿ èŠããããŸãã
- é©çšãããããžãã¯ã«å ããŠããã«ãã¹ã¬ããããã°ã©ãã³ã°ã®ä»æ§ãèæ ®ããå¿ èŠããããããã¹ã¬ããã»ãŒãã¡ãœãããå®è£ ããã®ã¯å°é£ã§ãã
- åæããªããã£ããç©æ¥µçã«äœ¿çšãããšãæçµçã«ã¢ããªã±ãŒã·ã§ã³ã®é床ãã·ã³ã°ã«ã¹ã¬ããå®è£ ãããé ããªãå¯èœæ§ããããŸãã
SchedulableObjectãã¿ãŒã³ã®åç
ãµãŒããŒããã¹ã¯ããããããã«ã¯Androidéçºã®äžçã«ãããŠãéãããžãã¹ããžãã¯ã¯ãå€ãã®å Žåãåå¥ã®ããã»ã¹ã«åé¢ãããŸãã åããã»ã¹å ã®ãµãŒãã¹éã®çžäºäœçšã¯ã·ã³ã°ã«ã¹ã¬ããã®ãŸãŸã§ãã ããŸããŸãªããã»ã¹ã®ãµãŒãã¹ã¯ãããŸããŸãªããã»ã¹ééä¿¡ã¡ã«ããºã ïŒCOM / DCOMãCorbaã.Net RemotingãBoost.Interprocessãªã©ïŒã䜿çšããŠäºãã«å¯Ÿè©±ããŸãã

æ®å¿µãªãããiOSéçºã®äžçã§ã¯ã1ã€ã®ããã»ã¹ã®ã¿ã«å¶éãããŠãããçŸç¶ã®ãŸãŸã§ã¯ãã®ã¢ãŒããã¯ãã£ã«é©åããŸããã ãã ããå¥ã®ããã»ã¹ãå¥ã®ã¹ã¬ããã«çœ®ãæããããã»ã¹éçžäºäœçšã®ã¡ã«ããºã ãéæ¥åŒã³åºãã«çœ®ãæããŠããããã¥ã¢ã§åçŸã§ããŸãã

ããæ£åŒã«ã¯ãå€æã®æ¬è³ªã¯æ¬¡ã®ãšããã§ãã
- 1ã€ã®åå¥ã®ã¯ãŒã¯ãããŒãéå§ããŸãã
- ã€ãã³ãåŠçãµã€ã¯ã«ãšããã«ã¡ãã»ãŒãžãé ä¿¡ããããã®ç¹å¥ãªãªããžã§ã¯ãã§ããã¹ã±ãžã¥ãŒã©ïŒè±èªã®ã¹ã±ãžã¥ãŒã©ããïŒã«é¢é£ä»ããŸãã
- åå¯å€ãªããžã§ã¯ããã¹ã±ãžã¥ãŒã©ãŒã®1ã€ã«é¢é£ä»ããŸãã ã¯ãŒã¯ãããŒã¹ã±ãžã¥ãŒã©ã«é¢é£ä»ãããããªããžã§ã¯ããå€ãã»ã©ãã¡ã€ã³ã¹ã¬ããããã®äž»ãªè²¬ä»»ã§ãããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®ã¬ã³ããªã³ã°ã«èŠããæéãé·ããªããŸãã
- ãã©ã³ããŒãšã®é¢ä¿ã«å¿ããŠããªããžã§ã¯ããçžäºäœçšããæ£ããæ¹æ³ãéžæããŸãã ã¹ã±ãžã¥ãŒã©ãäžè¬çãªå ŽåãçŽæ¥çãªã¡ãœããåŒã³åºãã«ãã£ãŠçžäºäœçšãçºçããããã§ãªãå Žåã¯ãç¹æ®ãªã€ãã³ãã®éä¿¡ãä»ããŠéæ¥çã«çºçããŸãã
ææ¡ãããã¢ãããŒãã¯ããã§ã«iOSã³ãã¥ããã£ã§æ¡çšãããŠããŸãã ããããFacebookã®äººæ°ã®ããReact Nativeãã¬ãŒã ã¯ãŒã¯ã®é«ã¬ãã«ã¢ãŒããã¯ãã£ã®å€èŠ³ã§ãã

ãã¹ãŠã®JavaScriptã³ãŒãã¯åå¥ã®ã¹ã¬ããã§å®è¡ããããã€ãã£ãã³ãŒããšã®å¯Ÿè©±ã¯ãéåæããªããžãä»ããŠã¡ãã»ãŒãžãéä¿¡ããããšã«ããéæ¥çãªåŒã³åºããéããŠè¡ãããŸã ã
SchedulableObjectãã¿ãŒã³ã³ã³ããŒãã³ã
SchedulableObjectãã¿ãŒã³ã¯ã5ã€ã®ã³ã³ããŒãã³ãã«åºã¥ããŠããŸãã 以äžã§ã¯ããããã®ããããã«ã€ããŠããã®å éšæ§é ãæãæ確ã«ç€ºãããã«ã責任ç¯å²ã決å®ãããçŽ æŽãªå®è£ ãææ¡ãããŸãã
ã€ãã³ã
iOSã®ã€ãã³ãã®æã䟿å©ãªæœè±¡åã¯ãå¿ èŠãªãªããžã§ã¯ãã¡ãœãããåŒã³åºããããããã¯ã§ãã
typealias Event = () -> Void
ã€ãã³ããã¥ãŒ
ãã¥ãŒå ã®ã€ãã³ãã¯ç°ãªãã¹ã¬ããããã®ãã®ã§ããããããã¥ãŒã«ã¯ã¹ã¬ããã»ãŒããªå®è£ ãå¿ èŠã§ãã å®éãã¢ããªã±ãŒã·ã§ã³ã³ã³ããŒãã³ãããã®ãã«ãã¹ã¬ããéçºã®ãã¹ãŠã®å°é£ãåŠçããã®ã¯åœŒå¥³ã§ãã
class EventQueue { private let semaphore = DispatchSemaphore(value: 1) private var events = [Event]() func pushEvent(event: @escaping Event) { semaphore.wait() events.append(event) semaphore.signal() } func resetEvents() -> [Event] { semaphore.wait() let currentEvents = events events = [Event]() semaphore.signal() return currentEvents } }
ã¡ãã»ãŒãžåŠçãµã€ã¯ã«
ãã¥ãŒããã®ã€ãã³ãã®å³å¯ãªé 次åŠçãå®è£ ããŸãã ã³ã³ããŒãã³ãã®ãã®ããããã£ã«ãããã³ã³ããŒãã³ããå®è£ ãããªããžã§ã¯ããžã®ãã¹ãŠã®åŒã³åºãããå³å¯ã«å®çŸ©ããã1ã€ã®ã¹ã¬ããã§è¡ãããŸãã
class RunLoop { let eventQueue = EventQueue() var disposed = false @objc func run() { while !disposed { for event in eventQueue.resetEvents() { event() } Thread.sleep(forTimeInterval: 0.1) } } }
iOS SDKã«ã¯ããã®ã³ã³ããŒãã³ãã®æšæºå®è£ ã§ããNSRunLoopããããŸãã
æµã
ã¡ãã»ãŒãžåŠçã«ãŒãã®ã³ãŒããå®è¡ããããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®ã«ãŒãã«ãªããžã§ã¯ãã iOS SDKã®æäœã¬ãã«ã®å®è£ ã¯NSThreadã¯ã©ã¹ã§ãã å®çšçã«ã¯ãNSOperationQueueãGrand Central Dispatchã®ãã¥ãŒãªã©ã®é«ã¬ãã«ã®ããªããã£ãã䜿çšããããšããå§ãããŸãã
ãã©ã³ããŒ
ç®çã®ãã¥ãŒã«ã€ãã³ããé ä¿¡ããã¡ã«ããºã ãæäŸããŸãã ã¯ã©ã€ã¢ã³ãã³ãŒãããªããžã§ã¯ãã¡ãœãããå®è¡ããã¡ã€ã³ã³ã³ããŒãã³ãã§ãããããSchedulableObjectãã€ã¯ããã¿ãŒã³ãšSchedulable Architectureãã¯ããã¿ãŒã³ã®äž¡æ¹ã«ååãä»ããŸãã
class Scheduler { private let runLoop = RunLoop() private let thread: Thread init() { self.thread = Thread(target:runLoop, selector:#selector(RunLoop.run), object:nil) thread.start() } func schedule(event: @escaping Event) { runLoop.eventQueue.pushEvent(event: event) } func dispose() { runLoop.disposed = true } }
SchedulableObject
éæ¥åŒã³åºãã®æšæºã€ã³ã¿ãŒãã§ã€ã¹ãæäŸããŸãã ã¿ãŒã²ãããªããžã§ã¯ãã«é¢ããŠã¯ã以äžã®äŸã®ããã«éçŽãšããŠæ©èœãã POSSchedulableObjectã©ã€ãã©ãªã®ããã«åºæ¬ã¯ã©ã¹ã®äž¡æ¹ãšããŠæ©èœããŸãã
class SchedulableObject<T> { private let object: T private let scheduler: Scheduler init(object: T, scheduler: Scheduler) { self.object = object self.scheduler = scheduler } func schedule(event: @escaping (T) -> Void) { scheduler.schedule { event(self.object) } } }
ãã¹ãŠããŸãšãã
以äžã®ããã°ã©ã ã¯ãã³ã³ãœãŒã«ã§ã³ã³ãœãŒã«ã«å ¥åãããæåãè€è£œããŸãã ã¡ã€ã³ã¹ã¬ããããåŒãåºãããããžãã¹ããžãã¯ã®å±€ã¯ãAssemblyã¯ã©ã¹ã«ãã£ãŠè¡šãããŸãã 次ã®2ã€ã®ãµãŒãã¹ãžã®ã¢ã¯ã»ã¹ãäœæããŠæäŸããŸãã
- ããªã³ã¿ãŒã¯ãã³ã³ãœãŒã«ã«äŸçµŠããè¡ãå°å·ããŸãã
- PrintOptionsProviderã䜿çšãããšãããªã³ã¿ãŒãµãŒãã¹ãæ§æã§ããŸãã
// // main.swift // SchedulableObjectDemo // class PrintOptionsProvider { var richFormatEnabled = false; } class Printer { private let optionsProvider: PrintOptionsProvider init(optionsProvider: PrintOptionsProvider) { self.optionsProvider = optionsProvider } func doWork(what: String) { if optionsProvider.richFormatEnabled { print("\(Thread.current): out \(what)") } else { print("out \(what)") } } } class Assembly { let backgroundScheduler = Scheduler() let printOptionsProvider: SchedulableObject<PrintOptionsProvider> let printer: SchedulableObject<Printer> init() { let optionsProvider = PrintOptionsProvider() self.printOptionsProvider = SchedulableObject<PrintOptionsProvider>( object: optionsProvider, scheduler: backgroundScheduler); self.printer = SchedulableObject<Printer>( object: Printer(optionsProvider: optionsProvider), scheduler: backgroundScheduler) } } let assembly = Assembly() while true { guard let value = readLine(strippingNewline: true) else { continue } if (value == "q") { assembly.backgroundScheduler.dispose() break; } assembly.printOptionsProvider.schedule( event: { (printOptionsProvider: PrintOptionsProvider) in printOptionsProvider.richFormatEnabled = arc4random() % 2 == 0 }) assembly.printer.schedule(event: { (printer: Printer) in printer.doWork(what: value) }) }
å¿ èŠã«å¿ããŠãã³ãŒãã®æåŸã®ãããã¯ãç°¡ç¥åã§ããŸãã
assembly.backgroundScheduler.schedule { assembly.printOptionsProvider.object.richFormatEnabled = arc4random() % 2 == 0 assembly.printer.object.doWork(what: value) }
ã¹ã±ãžã¥ãŒã«å¯èœãªãªããžã§ã¯ããšå¯Ÿè©±ããããã®ã«ãŒã«
äžèšã®ããã°ã©ã ã¯ãã¹ã±ãžã¥ãŒã«å¯èœãªãªããžã§ã¯ããšå¯Ÿè©±ããããã®2ã€ã®ã«ãŒã«ã瀺ããŠããŸãã
- åãã¹ã±ãžã¥ãŒã©ãŒããªããžã§ã¯ãã®ã¯ã©ã€ã¢ã³ããšåŒã³åºããããªããžã§ã¯ãã«é¢é£ä»ããããŠããå Žåãã¡ãœããã¯éåžžã®æ¹æ³ã§åŒã³åºãããŸãã ãã®ãããPrinterã¯PrintOptionsProviderãšçŽæ¥éä¿¡ããŸãã
- ãªããžã§ã¯ãã®ã¯ã©ã€ã¢ã³ããšåŒã³åºããããªããžã§ã¯ãã«ç°ãªãã¹ã±ãžã¥ãŒã©ãé¢é£ä»ããããŠããå Žåãã€ãã³ããéä¿¡ããããšã§éæ¥çã«åŒã³åºããè¡ãããŸãã äžèšã®äŸã§ã¯ãwhileã«ãŒãã¯ãŠãŒã¶ãŒå ¥åãèªã¿åããã¢ããªã±ãŒã·ã§ã³ã®ã¡ã€ã³ã¹ã¬ããã§å®è¡ãããããããžãã¹ããžãã¯ãªããžã§ã¯ãã«çŽæ¥ã¢ã¯ã»ã¹ã§ããŸããã 圌ã¯éæ¥çã«åœŒããšãããšãããŸã-ã€ãã³ããéãããšãéããŠã
ã¢ããªã±ãŒã·ã§ã³ã®å®å šãªãªã¹ãã¯ã ããã§å ¥æã§ããŸã ã
SchedulableObjectãã¿ãŒã³ã®æ¬ ç¹
ãã¿ãŒã³ã®ãã¹ãŠã®åªé ãã«å¯ŸããŠãããã¯æãåŽé¢ãæã£ãŠããŸãïŒé«äŸµè¥²æ§ã ãã®ãã¢ã¢ããªã±ãŒã·ã§ã³ã®ããã«ãåæèšèšäžã«Schedulable Architectureãæ·èšãããå Žåã¯ãã¹ãŠé 調ã§ãããçåœãæ¢åã®èšå€§ãªã³ãŒãããŒã¹ã«ãããåã蟌ãããšãäœåãªããããå Žåãã±ãŒã¹ã¯å®å šã«ç°ãªãé çªãåããŸãã ãã¿ãŒã³ã®Nã¹ã¬ããã®æ§è³ªã«ããã2ã€ã®å³ããèŠä»¶ãçããåºç¯å²ã«åã¶çµæãçããŸãã
èŠä»¶No. 1ïŒäžå€ã¢ãã«
ã¹ã¬ããéã移åãããã¹ãŠã®ãšã³ãã£ãã£ã¯ãäžå€ãŸãã¯ã¹ã±ãžã¥ãŒã«å¯èœã§ãªããã°ãªããŸããã ããã§ãªããã°ããã®ç¶æ ã®ç«¶äºçå€åã®åé¡ã®å šç¯å²ãé ããªãããšã¯ãããŸããã çŸåšãäžå€ã¢ãã«ãªããžã§ã¯ãã®äœ¿çšã«ã¯æ確ãªåŸåãèŠãããŸãã ãã®æåç·ã«ã¯ãããžãã¹ããžãã¯ãã¡ã€ã³ã¹ããªãŒã ããåé¢ããå¿ èŠæ§ã«çŽé¢ããŠããäŒæ¥ããããŸãã ãã®ãããã¯ã«é¢ããæãå°è±¡çãªè³æã®ãªã¹ãã次ã«ç€ºããŸãã
- Apple WWDCïŒSwiftã§å€åã䜿çšããããè¯ãã¢ããªã®æ§ç¯
- FacebookïŒComponentKit ...ã¯ã äžå€ã¢ãã«ããäžå€ã³ã³ããŒãã³ããžã®äžæ¹åã®ããŒã¿ãããŒã匷調ããŠããŸã
- DropboxïŒå®çšçãªã¯ãã¹ãã©ãããã©ãŒã ã¢ãã€ã«C ++éçº
- PinterestïŒiOSã¢ããªã®äžå€ã¢ãã«ãšããŒã¿ã®äžè²«æ§
- LinkedInïŒäžå€ã¢ãã«ã®äžè²«æ§ã®ç®¡ç
ããããä»æ¥ã®ã³ãŒãããŒã¹ã§ã¯ãå¯å€ã¢ãã«ã«ééããå¯èœæ§ããããŸãã ããã«ãCore DataãRealmãªã©ã®æ°žç¶åãã¬ãŒã ã¯ãŒã¯ã䜿çšããå Žåãreadwriteããããã£ã¯ããããæŽæ°ããå¯äžã®æ¹æ³ã§ãã Schedulable Architectureã®å°å ¥ã«ãããããããæŸæ£ããããã¢ãã«ãæäœããããã®ç¹å¥ãªã¡ã«ããºã ãæäŸãããŸãã ãããã£ãŠãRealmããŒã ã¯ä»¥äžãæäŸããŸãã ãããã£ãŠãRealmã®å¯äžã®å¶éã¯ãã¹ã¬ããéã§Realmãªããžã§ã¯ããæž¡ãããšãã§ããªãããšã§ãã å¥ã®ã¹ã¬ããã§åãããŒã¿ãå¿ èŠãªå Žåã¯ãä»ã®ã¹ã¬ããã§ãã®ããŒã¿ãç §äŒããã ãã§ãã Core Dataã«ã¯åé¿çããããŸãããç§ã®æèŠã§ã¯ãããã¯ãã¹ãŠéåžžã«äžäŸ¿ã§ããããåŽé¢ã«ãããã®ãã®ããã«èŠããŸãããããèšèšæ®µéã§ã¢ãŒããã¯ãã£ã«çµã¿èŸŒãããšã¯çµ¶å¯Ÿã«ããããªãã§ãã Facebookãã iOSã§ãã¥ãŒã¹ãã£ãŒãã50ïŒ è¿ãé«éåãã ããšããèšäºã§ãCore Dataã®æŸæ£ãçºè¡šããŸããã LinkedInã¯ãCore Dataã®åãæ¬ ç¹ãåŒçšããŠãæ°žç¶ããŒã¿ã¹ãã¬ãŒãžã®ãã¬ãŒã ã¯ãŒã¯ãæè¿å°å ¥ããŸãããã Rocket Dataã¯ãé床ãšå®å®æ§ãä¿èšŒãããå¯å€ã¢ãã«ã§ã¯ãªãäžå€ã¢ãã«ã§åäœãããããCore Dataã«é©ãããªãã·ã§ã³ã§ããã
èŠä»¶2ïŒãµãŒãã¹ã®ã¯ã©ã¹ã¿ãŒ
å¥ã®ã¹ããªãŒã ãžã®ç§»è¡ã¯ããªããžã§ã¯ãã®ã¯ã©ã¹ã¿ãŒå šäœãããã«å¯Ÿå¿ã§ããå Žåã«ã®ã¿æå³ããããŸãã ããŸããŸãªã·ããªãªã«åå ããŠãããµãŒãã¹ãããŸããŸãªã¹ããªãŒã ã«ååšããå Žåããããã®éã®è±å¯ãªéæ¥åŒã³åºãã«ãããä¿¡ããããªãã»ã©ã®å²åã®ã³ãŒããã©ã¹ããåŒãèµ·ããããŸãã

çŸåšãMail.Ru Cloudã§ã¯ã補åéçºã®äžç°ãšããŠãã¡ã€ã³ã¹ããªãŒã 以å€ã®ããžãã¹ããžãã¯ãåŸã ã«æºåããŠããŸãã ãã®ããããªãªãŒã¹ããšã«ãSchedulableObjectãã¿ãŒã³ãå®è£ ãããµãŒãã¹ã®æ°ãå¢ãããŠããŸãã ãããã®æ°ããå°é£ãªãã·ããªãªã®å®è£ ã«ååãªã¯ãªãã£ã«ã«ãã¹ã«éãããšããã«ãã¯ãŒã¯ãããŒã¹ã±ãžã¥ãŒã©ãåæã«èšå®ãããããžãã¹ããžãã¯ã«ãããã¬ãŒãã¯éå»ã®ãã®ã«ãªããŸãã
POSSchedulableObjectã©ã€ãã©ãª
POSSchedulableObjectã©ã€ãã©ãªã¯ãMail.Ru Clouds iOSã¢ããªã±ãŒã·ã§ã³ã®Schedulable Architectureãã¿ãŒã³ãå®å šã«å®è£ ããããã®éèŠãªèŠçŽ ã§ãã ã³ãŒãããŒã¹ã¯ã·ã³ã°ã«ã¹ã¬ããç¶æ ãã2ã¹ã¬ããç¶æ ã«ç§»è¡ããæºåãæŽã£ãã°ããã§ããããªãã¡ã¯ã¿ãªã³ã°ã¯æ¢ã«æçã§ãã POSSchedulableObjectã¯ãã¹ãŠã®ç®¡ç察象ãªããžã§ã¯ãã®åºæ¬ã¯ã©ã¹ãšããŠäœ¿çšãããããããã®ããããã£ã®äžéšã¯çŸåšã¢ã¯ãã£ãã«äœ¿çšãããŠããŸãã éèŠãªãã®ã®1ã€ã¯ããæµãã§ããã¹ããªãŒã ãããªããžã§ã¯ãã¡ãœãããžã®äžæ£ãªçŽæ¥åŒã³åºãã远跡ããããšã§ãã 1åãŸãã¯2å以äžPOSSchedulableObjectããç¹å®ã®ã¯ãŒã¯ãããŒããããžãã¹ããžãã¯ãµãŒãã¹ã«ã¢ã¯ã»ã¹ããããšããŠãããšããæå®ãéç¥ããŸããã äžè¬çãªçç±ã¯ãiOS 9ã§iOS SDKããã®ã¯ã©ã¹ã¡ãœããã®å®äºãããã¯ãã¢ããªã±ãŒã·ã§ã³ã®ã¡ã€ã³ã¹ã¬ããã§äœåããå ŽåãiOS 10ã§ãã®ã³ã³ãã©ã¯ããå€æŽãããªããšããç¡é§ãªåžæã§ãã
äžæ£ãªã¹ããªãŒã ããã®åŒã³åºããæ€åºããã¡ã«ããºã ã®å®è£ ã®ç¹å®ã®æ©èœã¯ãPOSSchedulableObjectã¯ã©ã¹ãšã¯å¥ã«äœ¿çšã§ããããšã§ãã ãã®ããããã£ã䜿çšããŠãViewControllersãžã®ã¡ãœããåŒã³åºããã¡ã€ã³ã¹ã¬ããã§ã®ã¿çºçããããšã確èªããŸããã 次ã®ããã«ãªããŸãã
@implementation UIViewController (MRCApp) - (BOOL)mrc_protectForMainThreadScheduler { POSScheduleProtectionOptions *options = [POSScheduleProtectionOptions include:[POSSchedulableObject selectorsForClass:self.class nonatomicOnly:YES predicate:^BOOL(SEL _Nonnull selector) { NSString *selectorName = NSStringFromSelector(selector); return [selectorName rangeOfString:@"_"].location != 0; }] exclude:[POSSchedulableObject selectorsForClass:[UIResponder class]]]; return [POSSchedulableObject protect:self forScheduler:[RACTargetQueueScheduler pos_mainThreadScheduler] options:options]; } @end
ã©ã€ãã©ãªã®è©³çŽ°ã«ã€ããŠã¯ã GitHubã®ãªããžããªã®èª¬æãåç §ããŠãã ãã ã iOS 7ã®ãµããŒããåæ¢ãããšããã«ãSwiftã®ããŒãžã§ã³ãããã«åŠçããŸãããã®æŠèŠã¯ããã¿ãŒã³ã®ã³ã³ããŒãã³ãã®ãªã¹ãã®äžéšãšããŠç€ºãããŸããã
ãããã«
SchedulableObjectãã¿ãŒã³ã¯ãã¡ã€ã³ã¹ã¬ããããã¢ããªã±ãŒã·ã§ã³ã®ããžãã¹ããžãã¯ãåãåºãããã®äœç³»çãªã¢ãããŒããæäŸããŸãã çµæãšããŠçããã¹ã±ãžã¥ãŒãªã³ã°å¯èœãªã¢ãŒããã¯ãã£ã¯ã2ã€ã®çç±ã§ããŸãã¹ã±ãŒãªã³ã°ããŸãã ãŸããã¯ãŒã¯ãããŒã®æ°ã¯ãµãŒãã¹ã®æ°ã«äŸåããŸããã 次ã«ããã«ãã¹ã¬ããéçºã®è€éãå šäœããã¢ããªã±ãŒã·ã§ã³ã¯ã©ã¹ããã€ã³ãã©ã¹ãã©ã¯ãã£ã¯ã©ã¹ã«ç§»è¡ããŸãã ã¢ãŒããã¯ãã£ã«ã¯ãèå³æ·±ãé ããå¯èœæ§ããããŸãã ããšãã°ã1ã€ã®ã¹ã¬ããã§ã¯ãªããè€æ°ã®ã¹ã¬ããã§ããžãã¹ããžãã¯ãåãåºãããšãã§ããŸãã ãããã®ããããã®åªå é äœãå€æŽããããšã«ããããã¯ãã¬ãã«ã§ããªããžã§ã¯ãã®åã¯ã©ã¹ã¿ãŒã«ããã·ã¹ãã ãªãœãŒã¹ã®äœ¿çšåŒ·åºŠãå€æŽããŸãã ããã¯ãããšãã°ãã¢ããªã±ãŒã·ã§ã³ã«ãã«ãã¢ã«ãŠã³ããå®è£ ããå Žåã«åœ¹ç«ã¡ãŸãã çŸåšã®ã¢ã«ãŠã³ãã®ããžãã¹ããžãã¯ã¡ãã»ãŒãžåŠçãµã€ã¯ã«ãå®è¡ãããã¹ããªãŒã ã®åªå 床ãäžããããšã«ããããŠãŒã¶ãŒã«æãé¢é£æ§ã®ããã¿ã¹ã¯ã®å®è¡ã匷åã§ããŸãã