Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
ÉîÈëÀí½â GCD£¨Ò»£©
 
×÷Õߣºlikendsl À´Ô´£ºDerek Selander ·¢²¼ÓÚ 2015-02-02
  2081  次浏览      32
 

ËäÈ» GCD ÒѾ­³öÏÖ¹ýÒ»¶Îʱ¼äÁË£¬µ«²»ÊÇÿ¸öÈ˶¼Ã÷ÁËÆäÖ÷ÒªÄÚÈÝ¡£ÕâÊÇ¿ÉÒÔÀí½âµÄ£»²¢·¢Ò»Ö±ºÜ¼¬ÊÖ£¬¶ø GCD ÊÇ»ùÓÚ C µÄ API £¬ËüÃǾÍÏñÒ»×é¼âÈñµÄÀâ½Ç´Á½ø Objective-C µÄƽ»¬ÊÀ½ç¡£ÎÒÃǽ«·ÖÁ½¸ö²¿·ÖµÄ½Ì³ÌÀ´ÉîÈëѧϰ GCD ¡£

ÔÚÕâÁ½²¿·ÖµÄϵÁÐÖУ¬µÚÒ»¸ö²¿·ÖµÄ½«½âÊÍ GCD ÊÇ×öʲôµÄ£¬²¢´ÓÐí¶à»ù±¾µÄ GCD º¯ÊýÖÐÕÒ³ö¼¸¸öÀ´Õ¹Ê¾¡£ÔÚµÚ¶þ²¿·Ö£¬Ä㽫ѧµ½¼¸¸ö GCD ÌṩµÄ¸ß¼¶º¯Êý¡£

ʲôÊÇ GCD

GCD ÊÇ libdispatch µÄÊг¡Ãû³Æ£¬¶ø libdispatch ×÷Ϊ Apple µÄÒ»¸ö¿â£¬Îª²¢·¢´úÂëÔÚ¶àºËÓ²¼þ£¨ÅÜ iOS »ò OS X £©ÉÏÖ´ÐÐÌṩÓÐÁ¦Ö§³Ö¡£Ëü¾ßÓÐÒÔÏÂÓŵ㣺

1.GCD ÄÜͨ¹ýÍÆ³Ù°º¹ó¼ÆËãÈÎÎñ²¢ÔÚºǫ́ÔËÐÐËüÃÇÀ´¸ÄÉÆÄãµÄÓ¦ÓõÄÏìÓ¦ÐÔÄÜ¡£

2.GCD Ìṩһ¸öÒ×ÓÚʹÓõIJ¢·¢Ä£ÐͶø²»½ö½öÖ»ÊÇËøºÍỊ̈߳¬ÒÔ°ïÖúÎÒÃDZܿª²¢·¢ÏÝÚå¡£

3.GCD ¾ßÓÐÔÚ³£¼ûģʽ£¨ÀýÈçµ¥Àý£©ÉÏÓøü¸ßÐÔÄܵÄÔ­ÓïÓÅ»¯ÄãµÄ´úÂëµÄDZÔÚÄÜÁ¦¡£

±¾½Ì³Ì¼ÙÉèÄã¶Ô Block ºÍ GCD Óлù´¡Á˽⡣Èç¹ûÄã¶Ô GCD ÍêȫİÉú£¬ÏÈ¿´¿´ iOS ÉϵĶàÏß³ÌºÍ GCD ÈëÃÅ½Ì³Ì Ñ§Ï°ÆäÒªÁì¡£

GCD ÊõÓï

ÒªÀí½â GCD £¬ÄãÒªÏÈÊìϤÓëÏ̺߳Ͳ¢·¢Ïà¹ØµÄ¼¸¸ö¸ÅÄî¡£ÕâÁ½Õß¶¼¿ÉÄÜÄ£ºýºÍ΢ÃËùÒÔÔÚ¿ªÊ¼ GCD ֮ǰÏȼòÒªµØ»Ø¹ËÒ»ÏÂËüÃÇ¡£

Serial vs. Concurrent ´®ÐÐ vs. ²¢·¢
ÕâЩÊõÓïÃèÊöµ±ÈÎÎñÏà¶ÔÓÚÆäËüÈÎÎñ±»Ö´ÐУ¬ÈÎÎñ´®ÐÐÖ´ÐоÍÊÇÿ´ÎÖ»ÓÐÒ»¸öÈÎÎñ±»Ö´ÐУ¬ÈÎÎñ²¢·¢Ö´ÐоÍÊÇÔÚͬһʱ¼ä¿ÉÒÔÓжà¸öÈÎÎñ±»Ö´ÐС£

ËäÈ»ÕâЩÊõÓï±»¹ã·ºÊ¹Ó㬱¾½Ì³ÌÖÐÄã¿ÉÒÔ½«ÈÎÎñÉ趨Ϊһ¸ö Objective-C µÄ Block ¡£²»Ã÷°×ʲôÊÇ Block £¿¿´¿´ iOS 5 ½Ì³ÌÖеÄÈçºÎʹÓà Block ¡£Êµ¼ÊÉÏ£¬ÄãÒ²¿ÉÒÔÔÚ GCD ÉÏʹÓú¯ÊýÖ¸Õ룬µ«ÔÚ´ó¶àÊý³¡¾°ÖУ¬Õâʵ¼ÊÉϸüÄÑÓÚʹÓá£Block ¾ÍÊǸü¼ÓÈÝÒ×Щ£¡

Synchronous vs. Asynchronous ͬ²½ vs. Òì²½

ÔÚ GCD ÖУ¬ÕâЩÊõÓïÃèÊöµ±Ò»¸öº¯ÊýÏà¶ÔÓÚÁíÒ»¸öÈÎÎñÍê³É£¬´ËÈÎÎñÊǸú¯ÊýÒªÇó GCD Ö´Ðеġ£Ò»¸öͬ²½º¯ÊýÖ»ÔÚÍê³ÉÁËËüÔ¤¶¨µÄÈÎÎñºó²Å·µ»Ø¡£

Ò»¸öÒì²½º¯Êý£¬¸ÕºÃÏà·´£¬»áÁ¢¼´·µ»Ø£¬Ô¤¶¨µÄÈÎÎñ»áÍê³Éµ«²»»áµÈËüÍê³É¡£Òò´Ë£¬Ò»¸öÒì²½º¯Êý²»»á×èÈûµ±Ç°Ïß³ÌÈ¥Ö´ÐÐÏÂÒ»¸öº¯Êý¡£

×¢Ò⡪¡ªµ±Äã¶Áµ½Í¬²½º¯Êý¡°×èÈû£¨Block£©¡±µ±Ç°Ị̈߳¬»òº¯ÊýÊÇÒ»¸ö¡°×èÈû¡±º¯Êý»ò×èÈû²Ù×÷ʱ£¬²»Òª±»¸ãºýÍ¿ÁË£¡¶¯´Ê¡°×èÈû¡±ÃèÊöÁ˺¯ÊýÈçºÎÓ°ÏìËüËùÔÚµÄÏ̶߳øÓëÃû´Ê¡°´úÂë¿é£¨Block£©¡±Ã»ÓйØÏµ¡£´úÂë¿éÃèÊöÁËÓà Objective-C ±àдµÄÒ»¸öÄäÃûº¯Êý£¬ËüÄܶ¨ÒåÒ»¸öÈÎÎñ²¢±»Ìá½»µ½ GCD ¡£

ÒëÕß×¢£ºÖÐÎIJ»»áÓÐÕâ¸öÎÊÌ⣬¡°×èÈû¡±ºÍ¡°´úÂë¿é¡±ÊÇÁ½¸ö´Ê¡£

Critical Section ÁÙ½çÇø

¾ÍÊÇÒ»¶Î´úÂë²»Äܱ»²¢·¢Ö´ÐУ¬Ò²¾ÍÊÇ£¬Á½¸öÏ̲߳»ÄÜͬʱִÐÐÕâ¶Î´úÂë¡£ÕâºÜ³£¼û£¬ÒòΪ´úÂëÈ¥²Ù×÷Ò»¸ö¹²Ïí×ÊÔ´£¬ÀýÈçÒ»¸ö±äÁ¿ÈôÄܱ»²¢·¢½ø³Ì·ÃÎÊ£¬ÄÇôËüºÜ¿ÉÄÜ»á±äÖÊ£¨ÒëÕß×¢£ºËüµÄÖµ²»ÔÙ¿ÉÐÅ£©¡£

Race Condition ¾ºÌ¬Ìõ¼þ

ÕâÖÖ×´¿öÊÇÖ¸»ùÓÚÌØ¶¨ÐòÁлòʱ»úµÄʼþµÄÈí¼þϵͳÒÔ²»ÊÜ¿ØÖƵķ½Ê½ÔËÐеÄÐÐΪ£¬ÀýÈç³ÌÐòµÄ²¢·¢ÈÎÎñÖ´ÐеÄÈ·ÇÐ˳Ðò¡£¾ºÌ¬Ìõ¼þ¿Éµ¼ÖÂÎÞ·¨Ô¤²âµÄÐÐΪ£¬¶ø²»ÄÜͨ¹ý´úÂë¼ì²éÁ¢¼´·¢ÏÖ¡£

Deadlock ËÀËø

Á½¸ö£¨ÓÐʱ¸ü¶à£©¶«Î÷¡ª¡ªÔÚ´ó¶àÊýÇé¿öÏ£¬ÊÇÏ̡߳ª¡ªËùνµÄËÀËøÊÇÖ¸ËüÃǶ¼¿¨×¡ÁË£¬²¢µÈ´ý¶Ô·½Íê³É»òÖ´ÐÐÆäËü²Ù×÷¡£µÚÒ»¸ö²»ÄÜÍê³ÉÊÇÒòΪËüÔڵȴýµÚ¶þ¸öµÄÍê³É¡£µ«µÚ¶þ¸öÒ²²»ÄÜÍê³É£¬ÒòΪËüÔڵȴýµÚÒ»¸öµÄÍê³É¡£

Thread Safe Ḭ̈߳²È«

Ḭ̈߳²È«µÄ´úÂëÄÜÔÚ¶àÏ̻߳ò²¢·¢ÈÎÎñÖб»°²È«µÄµ÷Ó㬶ø²»»áµ¼ÖÂÈκÎÎÊÌ⣨Êý¾ÝË𻵣¬±ÀÀ££¬µÈ£©¡£Ï̲߳»°²È«µÄ´úÂëÔÚij¸öʱ¿ÌÖ»ÄÜÔÚÒ»¸öÉÏÏÂÎÄÖÐÔËÐС£Ò»¸öḬ̈߳²È«´úÂëµÄÀý×ÓÊÇ NSDictionary ¡£Äã¿ÉÒÔÔÚͬһʱ¼äÔÚ¶à¸öÏß³ÌÖÐʹÓÃËü¶ø²»»áÓÐÎÊÌâ¡£ÁíÒ»·½Ã棬NSMutableDictionary ¾Í²»ÊÇḬ̈߳²È«µÄ£¬Ó¦¸Ã±£Ö¤Ò»´ÎÖ»ÄÜÓÐÒ»¸öÏ̷߳ÃÎÊËü¡£

Context Switch ÉÏÏÂÎÄÇл»

Ò»¸öÉÏÏÂÎÄÇл»Ö¸µ±ÄãÔÚµ¥¸ö½ø³ÌÀïÇл»Ö´Ðв»Í¬µÄÏß³Ìʱ´æ´¢Óë»Ö¸´Ö´ÐÐ״̬µÄ¹ý³Ì¡£Õâ¸ö¹ý³ÌÔÚ±àд¶àÈÎÎñÓ¦ÓÃʱºÜÆÕ±é£¬µ«»á´øÀ´Ò»Ð©¶îÍâµÄ¿ªÏú¡£

Concurrency vs Parallelism ²¢·¢Óë²¢ÐÐ

²¢·¢ºÍ²¢ÐÐͨ³£±»Ò»ÆðÌáµ½£¬ËùÒÔÖµµÃ»¨Ð©Ê±¼ä½âÊÍËüÃÇÖ®¼äµÄÇø±ð¡£

²¢·¢´úÂëµÄ²»Í¬²¿·Ö¿ÉÒÔ¡°Í¬²½¡±Ö´ÐС£È»¶ø£¬¸ÃÔõÑù·¢Éú»òÊÇ·ñ·¢Éú¶¼È¡¾öÓÚϵͳ¡£¶àºËÉ豸ͨ¹ý²¢ÐÐÀ´Í¬Ê±Ö´Ðжà¸öỊ̈߳»È»¶ø£¬ÎªÁËʹµ¥ºËÉ豸ҲÄÜʵÏÖÕâÒ»µã£¬ËüÃDZØÐëÏÈÔËÐÐÒ»¸öỊ̈߳¬Ö´ÐÐÒ»¸öÉÏÏÂÎÄÇл»£¬È»ºóÔËÐÐÁíÒ»¸öÏ̻߳ò½ø³Ì¡£Õâͨ³£·¢ÉúµØ×ã¹»¿ìÒÔÖ¸øÎÒÃDz¢·¢Ö´Ðеشí¾õ£¬ÈçÏÂͼËùʾ£º

ËäÈ»Äã¿ÉÒÔ±àд´úÂëÔÚ GCD ϲ¢·¢Ö´ÐУ¬µ« GCD »á¾ö¶¨ÓжàÉÙ²¢ÐеÄÐèÇó¡£²¢ÐÐÒªÇó²¢·¢£¬µ«²¢·¢²¢²»Äܱ£Ö¤²¢ÐС£

¸üÉîÈëµÄ¹ÛµãÊDz¢·¢Êµ¼ÊÉÏÊǹØÓÚ¹¹Ôì¡£µ±ÄãÔÚÄÔº£ÖÐÓà GCD ±àд´úÂ룬Äã×éÖ¯ÄãµÄ´úÂëÀ´±©Â¶ÄÜͬʱÔËÐеĶà¸ö¹¤×÷Ƭ¶Î£¬ÒÔ¼°²»ÄÜͬʱÔËÐеÄÄÇЩ¡£Èç¹ûÄãÏëÉîÈë´ËÖ÷Ì⣬¿´¿´ this excellent talk by Rob Pike ¡£

Queues ¶ÓÁÐ

GCD ÌṩÓÐ dispatch queues À´´¦Àí´úÂë¿é£¬ÕâЩ¶ÓÁйÜÀíÄãÌṩ¸ø GCD µÄÈÎÎñ²¢Óà FIFO ˳ÐòÖ´ÐÐÕâЩÈÎÎñ¡£Õâ¾Í±£Ö¤Á˵ÚÒ»¸ö±»Ìí¼Óµ½¶ÓÁÐÀïµÄÈÎÎñ»áÊǶÓÁÐÖеÚÒ»¸ö¿ªÊ¼µÄÈÎÎñ£¬¶øµÚ¶þ¸ö±»Ìí¼ÓµÄÈÎÎñ½«µÚ¶þ¸ö¿ªÊ¼£¬Èç´ËÖ±µ½¶ÓÁеÄÖյ㡣

ËùÓеĵ÷¶È¶ÓÁУ¨dispatch queues£©×ÔÉí¶¼ÊÇḬ̈߳²È«µÄ£¬ÄãÄÜ´Ó¶à¸öÏ̲߳¢ÐеķÃÎÊËüÃÇ¡£ GCD µÄÓŵãÊÇÏÔ¶øÒ×¼ûµÄ£¬¼´µ±ÄãÁ˽âÁ˵÷¶È¶ÓÁÐÈçºÎΪÄã×Ô¼º´úÂëµÄ²»Í¬²¿·ÖÌṩḬ̈߳²È«¡£¹ØÓÚÕâÒ»µãµÄ¹Ø¼üÊÇÑ¡ÔñÕýÈ·ÀàÐ͵ĵ÷¶È¶ÓÁкÍÕýÈ·µÄµ÷¶Èº¯ÊýÀ´Ìá½»ÄãµÄ¹¤×÷¡£

ÔÚ±¾½ÚÄã»á¿´µ½Á½ÖÖµ÷¶È¶ÓÁУ¬¶¼ÊÇÓÉ GCD ÌṩµÄ£¬È»ºó¿´Ò»Ð©ÃèÊöÈçºÎÓõ÷¶Èº¯ÊýÌí¼Ó¹¤×÷µ½¶ÓÁеÄÁÐ×Ó¡£

Serial Queues ´®ÐжÓÁÐ

´®ÐжÓÁÐÖеÄÈÎÎñÒ»´ÎÖ´ÐÐÒ»¸ö£¬Ã¿¸öÈÎÎñÖ»ÔÚǰһ¸öÈÎÎñÍê³ÉÊDzſªÊ¼¡£¶øÇÒ£¬Äã²»ÖªµÀÔÚÒ»¸ö Block ½áÊøºÍÏÂÒ»¸ö¿ªÊ¼Ö®¼äµÄʱ¼ä³¤¶È£¬ÈçÏÂͼËùʾ£º

ÕâЩÈÎÎñµÄÖ´ÐÐʱ»úÊܵ½ GCD µÄ¿ØÖÆ£»Î¨Ò»ÄÜÈ·±£µÄÊÂÇéÊÇ GCD Ò»´ÎÖ»Ö´ÐÐÒ»¸öÈÎÎñ£¬²¢ÇÒ°´ÕÕÎÒÃÇÌí¼Óµ½¶ÓÁеÄ˳ÐòÀ´Ö´ÐС£

ÓÉÓÚÔÚ´®ÐжÓÁÐÖв»»áÓÐÁ½¸öÈÎÎñ²¢·¢ÔËÐУ¬Òò´Ë²»»á³öÏÖͬʱ·ÃÎÊÁÙ½çÇøµÄ·çÏÕ£»Ïà¶ÔÓÚÕâЩÈÎÎñÀ´Ëµ£¬Õâ¾Í´Ó¾ºÌ¬Ìõ¼þϱ£»¤ÁËÁÙ½çÇø¡£ËùÒÔÈç¹û·ÃÎÊÁÙ½çÇøµÄΨһ·½Ê½ÊÇͨ¹ýÌá½»µ½µ÷¶È¶ÓÁеÄÈÎÎñ£¬ÄÇôÄã¾Í²»ÐèÒªµ£ÐÄÁÙ½çÇøµÄ°²È«ÎÊÌâÁË¡£

Concurrent Queues ²¢·¢¶ÓÁÐ
ÔÚ²¢·¢¶ÓÁÐÖеÄÈÎÎñÄܵõ½µÄ±£Ö¤ÊÇËüÃǻᰴÕÕ±»Ìí¼ÓµÄ˳Ðò¿ªÊ¼Ö´ÐУ¬µ«Õâ¾ÍÊÇÈ«²¿µÄ±£Ö¤ÁË¡£ÈÎÎñ¿ÉÄÜÒÔÈÎÒâ˳ÐòÍê³É£¬Äã²»»áÖªµÀºÎʱ¿ªÊ¼ÔËÐÐÏÂÒ»¸öÈÎÎñ£¬»òÕßÈÎÒâʱ¿ÌÓжàÉÙ Block ÔÚÔËÐС£ÔÙ˵һ±é£¬ÕâÍêȫȡ¾öÓÚ GCD ¡£

ÏÂͼչʾÁËÒ»¸öʾÀýÈÎÎñÖ´Ðмƻ®£¬GCD ¹ÜÀí×ÅËĸö²¢·¢ÈÎÎñ£º

×¢Òâ Block 1,2 ºÍ 3 ¶¼Á¢Âí¿ªÊ¼ÔËÐУ¬Ò»¸ö½ÓÒ»¸ö¡£ÔÚ Block 0 ¿ªÊ¼ºó£¬Block 1µÈ´ýÁ˺ÃÒ»»á¶ù²Å¿ªÊ¼¡£Í¬Ñù£¬ Block 3 ÔÚ Block 2 Ö®ºó²Å¿ªÊ¼£¬µ«ËüÏÈÓÚ Block 2 Íê³É¡£

ºÎʱ¿ªÊ¼Ò»¸ö Block Íêȫȡ¾öÓÚ GCD ¡£Èç¹ûÒ»¸ö Block µÄÖ´ÐÐʱ¼äÓëÁíÒ»¸öÖØµþ£¬Ò²ÊÇÓÉ GCD À´¾ö¶¨ÊÇ·ñ½«ÆäÔËÐÐÔÚÁíÒ»¸ö²»Í¬µÄºËÐÄÉÏ£¬Èç¹ûÄǸöºËÐÄ¿ÉÓ㬷ñÔò¾ÍÓÃÉÏÏÂÎÄÇл»µÄ·½Ê½À´Ö´Ðв»Í¬µÄ Block ¡£

ÓÐȤµÄÊÇ£¬ GCD Ìṩ¸øÄãÖÁÉÙÎå¸öÌØ¶¨µÄ¶ÓÁУ¬¿É¸ù¾Ý¶ÓÁÐÀàÐÍÑ¡ÔñʹÓá£

Queue Types ¶ÓÁÐÀàÐÍ

Ê×ÏÈ£¬ÏµÍ³Ìṩ¸øÄãÒ»¸ö½Ð×ö Ö÷¶ÓÁУ¨main queue£© µÄÌØÊâ¶ÓÁС£ºÍÆäËü´®ÐжÓÁÐÒ»Ñù£¬Õâ¸ö¶ÓÁÐÖеÄÈÎÎñÒ»´ÎÖ»ÄÜÖ´ÐÐÒ»¸ö¡£È»¶ø£¬ËüÄܱ£Ö¤ËùÓеÄÈÎÎñ¶¼ÔÚÖ÷Ïß³ÌÖ´ÐУ¬¶øÖ÷Ïß³ÌÊÇΨһ¿ÉÓÃÓÚ¸üРUI µÄÏ̡߳£Õâ¸ö¶ÓÁоÍÊÇÓÃÓÚ·¢ÉúÏûÏ¢¸ø UIView »ò·¢ËÍ֪ͨµÄ¡£

ϵͳͬʱÌṩ¸øÄãºÃ¼¸¸ö²¢·¢¶ÓÁС£ËüÃǽÐ×ö È«¾Öµ÷¶È¶ÓÁУ¨Global Dispatch Queues£© ¡£Ä¿Ç°µÄËĸöÈ«¾Ö¶ÓÁÐÓÐ×Ų»Í¬µÄÓÅÏȼ¶£ºbackground¡¢low¡¢default ÒÔ¼° high¡£ÒªÖªµÀ£¬Apple µÄ API Ò²»áʹÓÃÕâЩ¶ÓÁУ¬ËùÒÔÄãÌí¼ÓµÄÈκÎÈÎÎñ¶¼²»»áÊÇÕâЩ¶ÓÁÐÖÐΨһµÄÈÎÎñ¡£

×îºó£¬ÄãÒ²¿ÉÒÔ´´½¨×Ô¼ºµÄ´®ÐжÓÁлò²¢·¢¶ÓÁС£Õâ¾ÍÊÇ˵£¬ÖÁÉÙÓÐÎå¸ö¶ÓÁÐÈÎÄã´¦ÖãºÖ÷¶ÓÁС¢ËĸöÈ«¾Öµ÷¶È¶ÓÁУ¬ÔÙ¼ÓÉÏÈκÎÄã×Ô¼º´´½¨µÄ¶ÓÁС£

ÒÔÉÏÊǵ÷¶È¶ÓÁеĴó¿ò¼Ü£¡

GCD µÄ¡°ÒÕÊõ¡±¹é½áΪѡÔñºÏÊʵĶÓÁÐÀ´µ÷¶Èº¯ÊýÒÔÌá½»ÄãµÄ¹¤×÷¡£ÌåÑéÕâÒ»µãµÄ×îºÃ·½Ê½ÊÇ×ßÒ»±éϱߵÄÁÐ×Ó£¬ÎÒÃÇÑØÍ¾»áÌṩһЩһ°ãÐԵĽ¨Òé¡£

ÈëÃÅ

¼ÈÈ»±¾½Ì³ÌµÄÄ¿±êÊÇÓÅ»¯ÇÒ°²È«µÄʹÓà GCD µ÷ÓÃÀ´×Ô²»Í¬Ï̵߳ĴúÂ룬ÄÇôÄ㽫´ÓÒ»¸ö½üºõÍê³ÉµÄ½Ð×ö GooglyPuff µÄÏîÄ¿ÈëÊÖ¡£

GooglyPuff ÊÇÒ»¸öûÓÐÓÅ»¯£¬Ï̲߳»°²È«µÄÓ¦Óã¬ËüʹÓà Core Image µÄÈËÁ³¼ì²â API À´¸²¸ÇÒ»¶ÔÇú¹÷ÇòÑÛ¾¦µ½±»¼ì²âµ½µÄÈËÁ³ÉÏ¡£¶ÔÓÚ»ù±¾µÄͼÏñ£¬¿ÉÒÔ´ÓÏà»ú½º¾íÑ¡Ôñ£¬»òÓÃÔ¤ÉèºÃµÄURL´Ó»¥ÁªÍøÏÂÔØ¡£

Íê³ÉÏîÄ¿ÏÂÔØÖ®ºó£¬½«Æä½âѹµ½Ä³¸ö·½±ãµÄĿ¼£¬ÔÙÓà Xcode ´ò¿ªËü²¢±àÒëÔËÐС£Õâ¸öÓ¦Óÿ´ÆðÀ´ÈçÏÂͼËùʾ£º

×¢Òâµ±ÄãÑ¡Ôñ Le Internet Ñ¡ÏîÏÂÔØÍ¼Æ¬Ê±£¬Ò»¸ö UIAlertView ¹ýÔçµØµ¯³ö¡£Ä㽫ÔÚ±¾ÏµÁн̵̳صڶþ²¿·ÖÐÞ¸´Õâ¸öÎÊÌâ¡£

Õâ¸öÏîÄ¿ÖÐÓÐËĸöÓÐȤµÄÀࣺ

PhotoCollectionViewController£ºËüÊÇÓ¦ÓÿªÊ¼µÄµÚÒ»¸öÊÓͼ¿ØÖÆÆ÷¡£ËüÓÃËõÂÔͼչʾËùÓÐÑ¡¶¨µÄÕÕÆ¬¡£

PhotoDetailViewController£ºËüÖ´ÐÐÌí¼ÓÇú¹÷ÇòÑÛ¾¦µ½Í¼ÏñÉϵÄÂß¼­£¬²¢ÓÃÒ»¸ö UIScrollView À´ÏÔʾ½á¹ûͼƬ¡£

Photo£ºÕâÊÇÒ»¸öÀà´Ø£¬Ëü¸ù¾ÝÒ»¸ö NSURL µÄʵÀý»òÒ»¸ö ALAsset µÄʵÀýÀ´ÊµÀý»¯ÕÕÆ¬¡£Õâ¸öÀàÌṩһ¸öͼÏñ¡¢ËõÂÔͼÒÔ¼°´Ó URL ÏÂÔØµÄ״̬¡£

PhotoManager£ºËü¹ÜÀíËùÓÐ Photo µÄʵÀý.

Óà dispatch_async ´¦Àíºǫ́ÈÎÎñ

»Øµ½Ó¦Óò¢´ÓÄãµÄÏà»ú½º¾íÌí¼ÓһЩÕÕÆ¬»òʹÓà Le Internet Ñ¡ÏîÏÂÔØÒ»Ð©¡£

×¢ÒâÔÚ°´Ï PhotoCollectionViewController ÖеÄÒ»¸ö UICollectionViewCell µ½Éú³ÉÒ»¸öÐ嵀 PhotoDetailViewController Ö®¼ä»¨Á˶à¾Ãʱ¼ä£»Äã»á×¢Òâµ½Ò»¸öÃ÷ÏÔµÄÖͺó£¬ÌرðÊÇÔڱȽÏÂýµÄÉ豸Éϲ鿴ºÜ´óµÄͼ¡£

ÔÚÖØÔØ UIViewController µÄ viewDidLoad ʱÈÝÒ×¼ÓÈëÌ«¶àÔÓ²¨£¨too much clutter£©£¬Õâͨ³£»áÒýÆðÊÓͼ¿ØÖÆÆ÷³öÏÖǰ¸ü³¤µÄµÈ´ý¡£Èç¹û¿ÉÄÜ£¬×îºÃÊÇжÏÂһЩ¹¤×÷·Åµ½ºǫ́£¬Èç¹ûËüÃDz»ÊǾø¶Ô±ØÐëÒªÔËÐÐÔÚ¼ÓÔØÊ±¼äÀï¡£

ÕâÌýÆðÀ´ÏñÊÇ dispatch_async ÄÜ×öµÄÊÂÇ飡

´ò¿ª PhotoDetailViewController ²¢ÓÃÏÂÃæµÄʵÏÖÌæ»» viewDidLoad £º

- (void)viewDidLoad
{
[super viewDidLoad];
NSAssert(_image, @"Image not set; required to use view controller");
self.photoImageView.image = _image;

//Resize if neccessary to ensure it's not pixelated
if (_image.size.height <= self.photoImageView.bounds.size.height &&
_image.size.width <= self.photoImageView.bounds.size.width) {
[self.photoImageView setContentMode:UIViewContentModeCenter];
}

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // 1
UIImage *overlayImage = [self faceOverlayImageFromImage:_image];
dispatch_async(dispatch_get_main_queue(), ^{ // 2
[self fadeInNewImage:overlayImage]; // 3
});
});
}

ÏÂÃæÀ´ËµÃ÷ÉÏÃæµÄдúÂëËù×öµÄÊ£º

ÄãÊ×ÏȽ«¹¤×÷´ÓÖ÷Ïß³ÌÒÆµ½È«¾ÖÏ̡߳£ÒòΪÕâÊÇÒ»¸ö dispatch_async() £¬Block »á±»Òì²½µØÌá½»£¬Òâζ×ŵ÷ÓÃÏ̵߳ØÖ´Ðн«»á¼ÌÐø¡£Õâ¾ÍʹµÃ viewDidLoad ¸üÔçµØÔÚÖ÷Ïß³ÌÍê³É£¬ÈüÓÔØ¹ý³Ì¸Ð¾õÆðÀ´¸ü¼Ó¿ìËÙ¡£Í¬Ê±£¬Ò»¸öÈËÁ³¼ì²â¹ý³Ì»áÆô¶¯²¢½«ÔÚÉÔºóÍê³É¡£

ÔÚÕâÀÈËÁ³¼ì²â¹ý³ÌÍê³É£¬²¢Éú³ÉÁËÒ»¸öеÄͼÏñ¡£¼ÈÈ»ÄãҪʹÓôËÐÂͼÏñ¸üÐÂÄãµÄ UIImageView £¬ÄÇôÄã¾ÍÌí¼ÓÒ»¸öÐ嵀 Block µ½Ö÷Ï̡߳£¼Çס¡ª¡ªÄã±ØÐë×ÜÊÇÔÚÖ÷Ï̷߳ÃÎÊ UIKit µÄÀà¡£

×îºó£¬ÄãÓà fadeInNewImage: ¸üРUI £¬ËüÖ´ÐÐÒ»¸öµ­Èë¹ý³ÌÇл»µ½ÐµÄÇú¹÷ÇòÑÛ¾¦Í¼Ïñ¡£

±àÒë²¢ÔËÐÐÄãµÄÓ¦Óã»Ñ¡ÔñÒ»¸öͼÏñÈ»ºóÄã»á×¢Òâµ½ÊÓͼ¿ØÖÆÆ÷¼ÓÔØÃ÷ÏÔ±ä¿ì£¬Çú¹÷ÇòÑÛ¾¦ÉÔ΢ÔÚÖ®ºó¾Í¼ÓÉÏÁË¡£Õâ¸øÓ¦ÓôøÀ´Á˲»´íµÄЧ¹û£¬ºÍ֮ǰµÄÏÔʾ²î±ð¾Þ´ó¡£

½øÒ»²½£¬Èç¹ûÄãÊÔ׿ÓÔØÒ»¸ö³¬´óµÄͼÏñ£¬Ó¦Óò»»áÔÚ¼ÓÔØÊÓͼ¿ØÖÆÆ÷ÉÏ¡°¹Òס¡±£¬Õâ¾ÍʹµÃÓ¦ÓþßÓкܺÃÉìËõÐÔ¡£

ÕýÈç֮ǰÌáµ½µÄ£¬ dispatch_async Ìí¼ÓÒ»¸ö Block ¶¼¶ÓÁоÍÁ¢¼´·µ»ØÁË¡£ÈÎÎñ»áÔÚÖ®ºóÓÉ GCD ¾ö¶¨Ö´ÐС£µ±ÄãÐèÒªÔÚºǫִ́ÐÐÒ»¸ö»ùÓÚÍøÂç»ò CPU ½ôÕŵÄÈÎÎñʱ¾ÍʹÓà dispatch_async £¬ÕâÑù¾Í²»»á×èÈûµ±Ç°Ï̡߳£

ÏÂÃæÊÇÒ»¸ö¹ØÓÚÔÚ dispatch_async ÉÏÈçºÎÒÔ¼°ºÎʱʹÓò»Í¬µÄ¶ÓÁÐÀàÐ͵ĿìËÙÖ¸µ¼£º

×Ô¶¨Òå´®ÐжÓÁУºµ±ÄãÏë´®ÐÐÖ´Ðкǫ́ÈÎÎñ²¢×·×ÙËüʱ¾ÍÊÇÒ»¸öºÃÑ¡Ôñ¡£ÕâÏû³ýÁË×ÊÔ´ÕùÓã¬ÒòΪÄãÖªµÀÒ»´ÎÖ»ÓÐÒ»¸öÈÎÎñÔÚÖ´ÐС£×¢ÒâÈôÄãÐèÒªÀ´×Ôij¸ö·½·¨µÄÊý¾Ý£¬Äã±ØÐëÄÚÁªÁíÒ»¸ö Block À´ÕÒ»ØËü»ò¿¼ÂÇʹÓà dispatch_sync¡£

Ö÷¶ÓÁУ¨´®ÐУ©£ºÕâÊÇÔÚÒ»¸ö²¢·¢¶ÓÁÐÉÏÍê³ÉÈÎÎñºó¸üРUI µÄ¹²Í¬Ñ¡Ôñ¡£ÒªÕâÑù×ö£¬Ä㽫ÔÚÒ»¸ö Block ÄÚ²¿±àдÁíÒ»¸ö Block ¡£ÒÔ¼°£¬Èç¹ûÄãÔÚÖ÷¶ÓÁе÷Óà dispatch_async µ½Ö÷¶ÓÁУ¬ÄãÄÜÈ·±£Õâ¸öÐÂÈÎÎñ½«ÔÚµ±Ç°·½·¨Íê³ÉºóµÄij¸öʱ¼äÖ´ÐС£

²¢·¢¶ÓÁУºÕâÊÇÔÚºǫִ́ÐÐ·Ç UI ¹¤×÷µÄ¹²Í¬Ñ¡Ôñ¡£

ʹÓà dispatch_after ÑÓºó¹¤×÷

ÉÔ΢¿¼ÂÇÒ»ÏÂÓ¦ÓÃµÄ UX ¡£ÊÇ·ñÓû§µÚÒ»´Î´ò¿ªÓ¦ÓÃʱ»áÀ§»óÓÚ²»ÖªµÀ×öʲô£¿ÄãÊÇÕâÑùÂ𣿠:]

Èç¹ûÓû§µÄ PhotoManager ÀﻹûÓÐÈκÎÕÕÆ¬£¬ÄÇôÏÔʾһ¸öÌáʾ»áÊǸöºÃÖ÷Ò⣡Ȼ¶ø£¬ÄãͬÑùÒª¿¼ÂÇÓû§µÄÑÛ¾¦»áÈçºÎÔÚÖ÷ÆÁÄ»ÉÏä¯ÀÀ£ºÈç¹ûÄãÌ«¿ìµÄÏÔʾһ¸öÌáʾ£¬ËûÃǵÄÑÛ¾¦»¹ÅÇ»²ÔÚÊÓͼµÄÆäËü²¿·ÖÉÏ£¬ËûÃǺܿÉÄÜ»á´í¹ýËü¡£

ÏÔʾÌáʾ֮ǰÑÓ³ÙÒ»ÃëÖÓ¾Í×ã¹»²¶×½µ½Óû§µÄ×¢Ò⣬ËûÃÇ´ËʱÒѾ­µÚÒ»´Î¿´¹ýÁËÓ¦Óá£

Ìí¼ÓÈçÏ´úÂëµ½µ½ PhotoCollectionViewController.m ÖÐ showOrHideNavPrompt µÄ·ÏֹʵÏÖÀ

- (void)showOrHideNavPrompt
{
NSUInteger count = [[PhotoManager sharedManager] photos].count;
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); // 1
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ // 2
if (!count) {
[self.navigationItem setPrompt:@"Add photos with faces to Googlyify them!"];
} else {
[self.navigationItem setPrompt:nil];
}
});
}

showOrHideNavPrompt ÔÚ viewDidLoad ÖÐÖ´ÐУ¬ÒÔ¼° UICollectionView ±»ÖØÐ¼ÓÔØµÄÈκÎʱºò¡£°´ÕÕ×¢ÊÍÊý×Ö˳Ðò¿´¿´£º

ÄãÉùÃ÷ÁËÒ»¸ö±äÁ¿Ö¸¶¨ÒªÑÓ³ÙµÄʱ³¤¡£

È»ºóµÈ´ý delayInSeconds ¸ø¶¨µÄʱ³¤£¬ÔÙÒì²½µØÌí¼ÓÒ»¸ö Block µ½Ö÷Ï̡߳£

±àÒë²¢ÔËÐÐÓ¦Óá£Ó¦¸ÃÓÐÒ»¸öÇá΢µØÑÓ³Ù£¬ÕâÓÐÖúÓÚץסÓû§µÄ×¢ÒâÁ¦²¢Õ¹Ê¾ËùÒª×öµÄÊÂÇé¡£

dispatch_after ¹¤×÷ÆðÀ´¾ÍÏñÒ»¸öÑÓ³Ù°æµÄ dispatch_async ¡£ÄãÒÀÈ»²»ÄÜ¿ØÖÆÊµ¼ÊµÄÖ´ÐÐʱ¼ä£¬ÇÒÒ»µ© dispatch_after ·µ»ØÒ²¾Í²»ÄÜÔÙÈ¡ÏûËü¡£

²»ÖªµÀºÎʱÊʺÏʹÓà dispatch_after £¿

×Ô¶¨Òå´®ÐжÓÁУºÔÚÒ»¸ö×Ô¶¨Òå´®ÐжÓÁÐÉÏʹÓà dispatch_after ҪСÐÄ¡£Äã×îºÃ¼á³ÖʹÓÃÖ÷¶ÓÁÐ

Ö÷¶ÓÁУ¨´®ÐУ©£ºÊÇʹÓà dispatch_after µÄºÃÑ¡Ôñ£»Xcode ÌṩÁËÒ»¸ö²»´íµÄ×Ô¶¯Íê³ÉÄ£°æ¡£

²¢·¢¶ÓÁУºÔÚ²¢·¢¶ÓÁÐÉÏʹÓà dispatch_after ҲҪСÐÄ£»Äã»áÕâÑù×ö¾Í±È½Ïº±¼û¡£»¹ÊÇÔÚÖ÷¶ÓÁÐ×öÕâЩ²Ù×÷°É¡£

ÈÃÄãµÄµ¥ÀýḬ̈߳²È«

µ¥Àý£¬²»ÂÛϲ»¶»¹ÊÇÌÖÑᣬËüÃÇÔÚ iOS ÉϵÄÁ÷ÐÐÇé¿ö¾ÍÏñÍøÉϵÄè¡£ :]

Ò»¸ö³£¼ûµÄµ£ÓÇÊÇËüÃdz£³£²»ÊÇḬ̈߳²È«µÄ¡£Õâ¸öµ£ÓÇÊ®·ÖºÏÀí£¬»ùÓÚËüÃǵÄÓÃ;£ºµ¥Àý³£³£±»¶à¸ö¿ØÖÆÆ÷ͬʱ·ÃÎÊ¡£

µ¥ÀýµÄÏ̵߳£ÓÇ·¶Î§´Ó³õʼ»¯¿ªÊ¼£¬µ½ÐÅÏ¢µÄ¶ÁºÍд¡£PhotoManager À౻ʵÏÖΪµ¥Àý¡ª¡ªËüÔÚĿǰµÄ״̬ϾͻᱻÕâЩÎÊÌâËùÀ§ÈÅ¡£Òª¿´¿´ÊÂÇéÈçºÎºÜ¿ìµØÊ§È¥¿ØÖÆ£¬Ä㽫ÔÚµ¥ÀýʵÀýÉÏ´´½¨Ò»¸ö¿ØÖƺõľºÌ¬Ìõ¼þ¡£

µ¼º½µ½ PhotoManager.m ²¢ÕÒµ½ sharedManager £»Ëü¿´ÆðÀ´ÈçÏ£º

+ (instancetype)sharedManager    
{
static PhotoManager *sharedPhotoManager = nil;
if (!sharedPhotoManager) {
sharedPhotoManager = [[PhotoManager alloc] init];
sharedPhotoManager->_photosArray = [NSMutableArray array];
}
return sharedPhotoManager;
}

µ±Ç°×´Ì¬Ï£¬´úÂëÏ൱¼òµ¥£»Äã´´½¨ÁËÒ»¸öµ¥Àý²¢³õʼ»¯Ò»¸ö½Ð×ö photosArray µÄ NSMutableArray ÊôÐÔ¡£

È»¶ø£¬if Ìõ¼þ·ÖÖ§²»ÊÇḬ̈߳²È«µÄ£»Èç¹ûÄã¶à´Îµ÷ÓÃÕâ¸ö·½·¨£¬ÓÐÒ»¸ö¿ÉÄÜÐÔÊÇÔÚij¸öỊ̈߳¨¾Í½ÐËüÏß³ÌA£©ÉϽøÈë if Óï¾ä¿é²¢¿ÉÄÜÔÚ sharedPhotoManager ±»·ÖÅäÄÚ´æÇ°·¢ÉúÒ»¸öÉÏÏÂÎÄÇл»¡£È»ºóÁíÒ»¸öỊ̈߳¨Ïß³ÌB£©¿ÉÄܽøÈë if £¬·ÖÅäµ¥ÀýʵÀýµÄÄڴ棬ȻºóÍ˳ö¡£

µ±ÏµÍ³ÉÏÏÂÎÄÇл»»ØÏß³ÌA£¬Äã»á·ÖÅäÁíÍâÒ»¸öµ¥ÀýʵÀýµÄÄڴ棬ȻºóÍ˳ö¡£ÔÚÄǸöʱ¼äµã£¬ÄãÓÐÁËÁ½¸öµ¥ÀýµÄʵÀý¡ª¡ªºÜÃ÷ÏÔÕâ²»ÊÇÄãÏëÒªµÄ£¨ÒëÕß×¢£ºÕ⻹Äܽе¥ÀýÂ𣿣©£¡

ÒªÇ¿ÖÆÕâ¸ö£¨¾ºÌ¬£©Ìõ¼þ·¢Éú£¬Ìæ»» PhotoManager.m ÖÐµÄ sharedManager ΪÏÂÃæµÄʵÏÖ£º

+ (instancetype)sharedManager  
{
static PhotoManager *sharedPhotoManager = nil;
if (!sharedPhotoManager) {
[NSThread sleepForTimeInterval:2];
sharedPhotoManager = [[PhotoManager alloc] init];
NSLog(@"Singleton has memory address at: %@", sharedPhotoManager);
[NSThread sleepForTimeInterval:2];
sharedPhotoManager->_photosArray = [NSMutableArray array];
}
return sharedPhotoManager;
}

ÉÏÃæµÄ´úÂëÖÐÄãÓà NSThread µÄ sleepForTimeInterval: Àà·½·¨À´Ç¿ÖÆ·¢ÉúÒ»¸öÉÏÏÂÎÄÇл»¡£

´ò¿ª AppDelegate.m ²¢Ìí¼ÓÈçÏ´úÂëµ½ application:didFinishLaunchingWithOptions: µÄ×ʼ´¦£º

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
[PhotoManager sharedManager];
});

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
[PhotoManager sharedManager];
});

ÕâÀï´´½¨Á˶à¸öÒì²½²¢·¢µ÷ÓÃÀ´ÊµÀý»¯µ¥Àý£¬È»ºóÒý·¢ÉÏÃæÃèÊöµÄ¾ºÌ¬Ìõ¼þ¡£

±àÒë²¢ÔËÐÐÏîÄ¿£»²é¿´¿ØÖÆÌ¨Êä³ö£¬Äã»á¿´µ½¶à¸öµ¥Àý±»ÊµÀý»¯£¬ÈçÏÂËùʾ£º

×¢Òâµ½ÕâÀïÓкü¸ÐÐÏÔʾ×Ų»Í¬µØÖ·µÄµ¥ÀýʵÀý¡£ÕâÃ÷ÏÔÎ¥±³Á˵¥ÀýµÄÄ¿µÄ£¬¶Ô°É£¿:]

Õâ¸öÊä³öÏòÄãչʾÁËÁÙ½çÇø±»Ö´Ðжà´Î£¬¶øËüÖ»Ó¦¸ÃÖ´ÐÐÒ»´Î¡£ÏÖÔÚ£¬¹ÌÈ»ÊÇÄã×Ô¼ºÇ¿ÖÆÕâÑùµÄ×´¿ö·¢Éú£¬µ«Äã¿ÉÒÔÏëÏñÒ»ÏÂÕâ¸ö×´¿ö»áÔõÑùÔÚÎÞÒâ¼ä·¢Éú¡£

×¢Ò⣺»ùÓÚÆäËüÄãÎÞ·¨¿ØÖƵÄϵͳʼþ£¬NSLog µÄÊýÁ¿ÓÐʱ»áÏÔʾ¶à¸ö¡£Ïß³ÌÎÊÌ⼫ÆäÄÑÒÔµ÷ÊÔ£¬ÒòΪËüÃÇÍùÍùÄÑÒÔÖØÏÖ¡£

Òª¾ÀÕýÕâ¸ö×´¿ö£¬ÊµÀý»¯´úÂëÓ¦¸ÃÖ»Ö´ÐÐÒ»´Î£¬²¢×èÈûÆäËüʵÀýÔÚ if Ìõ¼þµÄÁÙ½çÇøÔËÐС£Õâ¸ÕºÃ¾ÍÊÇ dispatch_once ÄÜ×öµÄÊ¡£

ÔÚµ¥Àý³õʼ»¯·½·¨ÖÐÓà dispatch_once È¡´ú if Ìõ¼þÅжϣ¬ÈçÏÂËùʾ£º

+ (instancetype)sharedManager
{
static PhotoManager *sharedPhotoManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[NSThread sleepForTimeInterval:2];
sharedPhotoManager = [[PhotoManager alloc] init];
NSLog(@"Singleton has memory address at: %@", sharedPhotoManager);
[NSThread sleepForTimeInterval:2];
sharedPhotoManager->_photosArray = [NSMutableArray array];
});
return sharedPhotoManager;
}

±àÒë²¢ÔËÐÐÄãµÄÓ¦Ó㻲鿴¿ØÖÆÌ¨Êä³ö£¬Äã»á¿´µ½ÓÐÇÒ½öÓÐÒ»¸öµ¥ÀýµÄʵÀý¡ª¡ªÕâ¾ÍÊÇÄã¶Ôµ¥ÀýµÄÆÚÍû£¡:]

ÏÖÔÚÄãÒѾ­Ã÷°×ÁË·ÀÖ¹¾ºÌ¬Ìõ¼þµÄÖØÒªÐÔ£¬´Ó AppDelegate.m ÖÐÒÆ³ý dispatch_async Óï¾ä£¬²¢ÓÃÏÂÃæµÄʵÏÖÌæ»» PhotoManagerµ¥ÀýµÄ³õʼ»¯£º

+ (instancetype)sharedManager
{
static PhotoManager *sharedPhotoManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedPhotoManager = [[PhotoManager alloc] init];
sharedPhotoManager->_photosArray = [NSMutableArray array];
});
return sharedPhotoManager;
}

dispatch_once() ÒÔḬ̈߳²È«µÄ·½Ê½Ö´ÐÐÇÒ½öÖ´ÐÐÆä´úÂë¿éÒ»´Î¡£ÊÔͼ·ÃÎÊÁÙ½çÇø£¨¼´´«µÝ¸ø dispatch_once µÄ´úÂ룩µÄ²»Í¬µÄÏ̻߳áÔÚÁÙ½çÇøÒÑÓÐÒ»¸öÏ̵߳ÄÇé¿öϱ»×èÈû£¬Ö±µ½ÁÙ½çÇøÍê³ÉΪֹ¡£

ÐèÒª¼ÇסµÄÊÇ£¬ÕâÖ»ÊÇÈ÷ÃÎʹ²ÏíʵÀýḬ̈߳²È«¡£Ëü¾ø¶ÔûÓÐÈÃÀà±¾ÉíḬ̈߳²È«¡£ÀàÖпÉÄÜ»¹ÓÐÆäËü¾ºÌ¬Ìõ¼þ£¬ÀýÈçÈκβÙ×ÝÄÚ²¿Êý¾ÝµÄÇé¿ö¡£ÕâЩÐèÒªÓÃÆäËü·½Ê½À´±£Ö¤Ḭ̈߳²È«£¬ÀýÈçͬ²½·ÃÎÊÊý¾Ý£¬Ä㽫ÔÚÏÂÃæ¼¸¸öС½Ú¿´µ½¡£

´¦Àí¶ÁÕßÓëдÕßÎÊÌâ

Ḭ̈߳²È«ÊµÀý²»ÊÇ´¦Àíµ¥ÀýʱµÄΨһÎÊÌâ¡£Èç¹ûµ¥ÀýÊôÐÔ±íʾһ¸ö¿É±ä¶ÔÏó£¬ÄÇôÄã¾ÍÐèÒª¿¼ÂÇÊÇ·ñÄǸö¶ÔÏó×ÔÉíḬ̈߳²È«¡£

Èç¹ûÎÊÌâÖеÄÕâ¸ö¶ÔÏóÊÇÒ»¸ö Foundation ÈÝÆ÷À࣬ÄÇô´ð°¸ÊÇ¡ª¡ª¡°ºÜ¿ÉÄܲ»°²È«¡±£¡Apple ά»¤Ò»¸öÓÐÓÃÇÒÓÐЩÐ宵ÄÁÐ±í£¬ÖÚ¶àµÄ Foundation Àà¶¼²»ÊÇḬ̈߳²È«µÄ¡£ NSMutableArray£¬ÒÑÓÃÓÚÄãµÄµ¥Àý£¬ÕýÔÚÄǸöÁбíÀïÐÝÏ¢¡£

ËäÈ»Ðí¶àÏ߳̿ÉÒÔͬʱ¶ÁÈ¡ NSMutableArray µÄÒ»¸öʵÀý¶ø²»»á²úÉúÎÊÌ⣬µ«µ±Ò»¸öÏß³ÌÕýÔÚ¶ÁȡʱÈÃÁíÍâÒ»¸öÏß³ÌÐÞ¸ÄÊý×é¾ÍÊDz»°²È«µÄ¡£ÄãµÄµ¥ÀýÔÚĿǰµÄ×´¿öϲ»ÄÜÔ¤·ÀÕâÖÖÇé¿öµÄ·¢Éú¡£

Òª·ÖÎöÕâ¸öÎÊÌ⣬¿´¿´ PhotoManager.m ÖÐµÄ addPhoto:£¬×ªÔØÈçÏ£º

- (void)addPhoto:(Photo *)photo
{
if (photo) {
[_photosArray addObject:photo];
dispatch_async(dispatch_get_main_queue(), ^{
[self postContentAddedNotification];
});
}
}

ÕâÊÇÒ»¸öд·½·¨£¬ËüÐÞ¸ÄÒ»¸ö˽ÓпɱäÊý×é¶ÔÏó¡£

ÏÖÔÚ¿´¿´ photos £¬×ªÔØÈçÏ£º

- (NSArray *)photos
{
return [NSArray arrayWithArray:_photosArray];
}

ÕâÊÇËùνµÄ¶Á·½·¨£¬Ëü¶ÁÈ¡¿É±äÊý×é¡£ËüΪµ÷ÓÃÕßÉú³ÉÒ»¸ö²»¿É±äµÄ¿½±´£¬·ÀÖ¹µ÷ÓÃÕß²»µ±µØ¸Ä±äÊý×飬µ«Õâ²»ÄÜÌṩÈκα£»¤À´¶Ô¿¹µ±Ò»¸öÏ̵߳÷ÓöÁ·½·¨ photos µÄͬʱÁíÒ»¸öÏ̵߳÷ÓÃд·½·¨ addPhoto: ¡£

Õâ¾ÍÊÇÈí¼þ¿ª·¢Öо­µäµÄ¶ÁÕßдÕßÎÊÌâ¡£GCD ͨ¹ýÓà dispatch barriers ´´½¨Ò»¸ö¶ÁÕßдÕßËø ÌṩÁËÒ»¸öÓÅÑŵĽâ¾ö·½°¸¡£

Dispatch barriers ÊÇÒ»×麯Êý£¬ÔÚ²¢·¢¶ÓÁÐÉϹ¤×÷ʱ°çÑÝÒ»¸ö´®ÐÐʽµÄÆ¿¾±¡£Ê¹Óà GCD µÄÕϰ­£¨barrier£©API È·±£Ìá½»µÄ Block ÔÚÄǸöÌØ¶¨Ê±¼äÉÏÊÇÖ¸¶¨¶ÓÁÐÉÏΨһ±»Ö´ÐеÄÌõÄ¿¡£Õâ¾ÍÒâζ×ÅËùÓеÄÏÈÓÚµ÷¶ÈÕϰ­Ìá½»µ½¶ÓÁеÄÌõÄ¿±ØÄÜÔÚÕâ¸ö Block Ö´ÐÐǰÍê³É¡£

µ±Õâ¸ö Block µÄʱ»úµ½´ï£¬µ÷¶ÈÕϰ­Ö´ÐÐÕâ¸ö Block ²¢È·±£ÔÚÄǸöʱ¼äÀï¶ÓÁв»»áÖ´ÐÐÈÎºÎÆäËü Block ¡£Ò»µ©Íê³É£¬¶ÓÁоͷµ»Øµ½ËüĬÈϵÄʵÏÖ״̬¡£ GCD ÌṩÁËͬ²½ºÍÒì²½Á½ÖÖÕϰ­º¯Êý¡£

ÏÂͼÏÔʾÁËÕϰ­º¯Êý¶Ô¶à¸öÒì²½¶ÓÁеÄÓ°Ï죺

×¢Òâµ½Õý³£²¿·ÖµÄ²Ù×÷¾ÍÈçͬһ¸öÕý³£µÄ²¢·¢¶ÓÁС£µ«µ±Õϰ­Ö´ÐÐʱ£¬Ëü±¾ÖÊÉϾÍÈçͬһ¸ö´®ÐжÓÁС£Ò²¾ÍÊÇ£¬Õϰ­ÊÇΨһÔÚÖ´ÐеÄÊÂÎï¡£ÔÚÕϰ­Íê³Éºó£¬¶ÓÁлص½Ò»¸öÕý³£²¢·¢¶ÓÁеÄÑù×Ó¡£

ÏÂÃæÊÇÄãºÎʱ»á¡ª¡ªºÍ²»»á¡ª¡ªÊ¹ÓÃÕϰ­º¯ÊýµÄÇé¿ö£º

1.×Ô¶¨Òå´®ÐжÓÁУºÒ»¸öºÜ»µµÄÑ¡Ôñ£»Õϰ­²»»áÓÐÈκΰïÖú£¬ÒòΪ²»¹ÜÔõÑù£¬Ò»¸ö´®ÐжÓÁÐÒ»´Î¶¼Ö»Ö´ÐÐÒ»¸ö²Ù×÷¡£

2.È«¾Ö²¢·¢¶ÓÁУºÒªÐ¡ÐÄ£»Õâ¿ÉÄܲ»ÊÇ×îºÃµÄÖ÷Ò⣬ÒòΪÆäËüϵͳ¿ÉÄÜÔÚʹÓöÓÁжøÇÒÄã²»ÄÜ¢¶ÏËüÃÇֻΪÄã×Ô¼ºµÄÄ¿µÄ¡£

3.×Ô¶¨Òå²¢·¢¶ÓÁУºÕâ¶ÔÓÚÔ­×Ó»òÁÙ½çÇø´úÂëÀ´ËµÊǼ«¼ÑµÄÑ¡Ôñ¡£ÈκÎÄãÔÚÉèÖûòʵÀý»¯µÄÐèÒªḬ̈߳²È«µÄÊÂÎï¶¼ÊÇʹÓÃÕϰ­µÄ×î¼ÑºòÑ¡¡£

ÓÉÓÚÉÏÃæÎ¨Ò»ÏñÑùµÄÑ¡ÔñÊÇ×Ô¶¨Òå²¢·¢¶ÓÁУ¬Ä㽫´´½¨Ò»¸öÄã×Ô¼ºµÄ¶ÓÁÐÈ¥´¦ÀíÄãµÄÕϰ­º¯Êý²¢·Ö¿ª¶ÁºÍдº¯Êý¡£ÇÒÕâ¸ö²¢·¢¶ÓÁн«ÔÊÐí¶à¸ö¶à²Ù×÷ͬʱ½øÐС£

´ò¿ª PhotoManager.m£¬Ìí¼ÓÈçÏÂ˽ÓÐÊôÐÔµ½ÀàÀ©Õ¹ÖУº

@interface PhotoManager ()
@property (nonatomic,strong,readonly) NSMutableArray *photosArray;
@property (nonatomic, strong) dispatch_queue_t concurrentPhotoQueue; ///< Add this
@end

ÕÒµ½ addPhoto: ²¢ÓÃÏÂÃæµÄʵÏÖÌæ»»Ëü£º

- (void)addPhoto:(Photo *)photo
{
if (photo) { // 1
dispatch_barrier_async(self.concurrentPhotoQueue, ^{ // 2
[_photosArray addObject:photo]; // 3
dispatch_async(dispatch_get_main_queue(), ^{ // 4
[self postContentAddedNotification];
});
});
}
}

ÄãÐÂдµÄº¯ÊýÊÇÕâÑù¹¤×÷µÄ£º

1.ÔÚÖ´ÐÐÏÂÃæËùÓеŤ×÷ǰ¼ì²éÊÇ·ñÓкϷ¨µÄÏàÆ¬¡£

2.Ìí¼Óд²Ù×÷µ½ÄãµÄ×Ô¶¨Òå¶ÓÁС£µ±ÁÙ½çÇøÔÚÉÔºóÖ´ÐÐʱ£¬Õ⽫ÊÇÄã¶ÓÁÐÖÐΨһִÐеÄÌõÄ¿¡£

3.ÕâÊÇÌí¼Ó¶ÔÏóµ½Êý×éµÄʵ¼Ê´úÂë¡£ÓÉÓÚËüÊÇÒ»¸öÕϰ­ Block £¬Õâ¸ö Block ÓÀÔ¶²»»áͬʱºÍÆäËü Block Ò»ÆðÔÚ concurrentPhotoQueue ÖÐÖ´ÐС£

4.×îºóÄã·¢ËÍÒ»¸ö֪ͨ˵Ã÷Íê³ÉÁËÌí¼ÓͼƬ¡£Õâ¸ö֪ͨ½«ÔÚÖ÷Ï̱߳»·¢ËÍÒòΪËü½«»á×öһЩ UI ¹¤×÷£¬ËùÒÔÔÚ´ËΪÁË֪ͨ£¬ÄãÒì²½µØµ÷¶ÈÁíÒ»¸öÈÎÎñµ½Ö÷Ï̡߳£

Õâ¾Í´¦ÀíÁËд²Ù×÷£¬µ«Ä㻹ÐèҪʵÏÖ photos ¶Á·½·¨²¢ÊµÀý»¯ concurrentPhotoQueue ¡£

ÔÚдÕß´òÈŵÄÇé¿öÏ£¬ÒªÈ·±£Ḭ̈߳²È«£¬ÄãÐèÒªÔÚ concurrentPhotoQueue ¶ÓÁÐÉÏÖ´ÐжÁ²Ù×÷¡£¼ÈÈ»ÄãÐèÒª´Óº¯Êý·µ»Ø£¬Äã¾Í²»ÄÜÒì²½µ÷¶Èµ½¶ÓÁУ¬ÒòΪÄÇÑùÔÚ¶ÁÕߺ¯Êý·µ»ØÖ®Ç°²»Ò»¶¨ÔËÐС£

ÔÚÕâÖÖÇé¿öÏ£¬dispatch_sync ¾ÍÊÇÒ»¸ö¾øºÃµÄºòÑ¡¡£

dispatch_sync() ͬ²½µØÌá½»¹¤×÷²¢ÔÚ·µ»ØÇ°µÈ´ýËüÍê³É¡£Ê¹Óà dispatch_sync ¸ú×ÙÄãµÄµ÷¶ÈÕϰ­¹¤×÷£¬»òÕßµ±ÄãÐèÒªµÈ´ý²Ù×÷Íê³Éºó²ÅÄÜʹÓà Block ´¦Àí¹ýµÄÊý¾Ý¡£Èç¹ûÄãʹÓõڶþÖÖÇé¿ö×öÊ£¬Ä㽫²»Ê±¿´µ½Ò»¸ö __block ±äÁ¿Ð´ÔÚ dispatch_sync ·¶Î§Ö®Í⣬ÒԱ㷵»ØÊ±ÔÚ dispatch_sync ʹÓô¦Àí¹ýµÄ¶ÔÏó¡£

µ«ÄãÐèÒªºÜСÐÄ¡£ÏëÏñÈç¹ûÄãµ÷Óà dispatch_sync ²¢·ÅÔÚÄãÒÑÔËÐÐ×ŵĵ±Ç°¶ÓÁС£Õâ»áµ¼ÖÂËÀËø£¬ÒòΪµ÷ÓûáÒ»Ö±µÈ´ýÖ±µ½ Block Íê³É£¬µ« Block ²»ÄÜÍê³É£¨ËüÉõÖÁ²»»á¿ªÊ¼£¡£©£¬Ö±µ½µ±Ç°ÒѾ­´æÔÚµÄÈÎÎñÍê³É£¬¶øµ±Ç°ÈÎÎñÎÞ·¨Íê³É£¡Õ⽫ÆÈʹÄã×Ô¾õÓÚÄãÕý´ÓÄĸö¶ÓÁе÷Ó᪡ªÒÔ¼°ÄãÕýÔÚ´«µÝ½øÈëÄĸö¶ÓÁС£

ÏÂÃæÊÇÒ»¸ö¿ìËÙ×ÜÀÀ£¬¹ØÓÚÔÚºÎʱÒÔ¼°ºÎ´¦Ê¹Óà dispatch_sync £º

1.×Ô¶¨Òå´®ÐжÓÁУºÔÚÕâ¸ö×´¿öÏÂÒª·Ç³£Ð¡ÐÄ£¡Èç¹ûÄãÕýÔËÐÐÔÚÒ»¸ö¶ÓÁв¢µ÷Óà dispatch_sync ·ÅÔÚͬһ¸ö¶ÓÁУ¬ÄÇÄã¾Í°Ù·Ö°ÙµØ´´½¨ÁËÒ»¸öËÀËø¡£

2.Ö÷¶ÓÁУ¨´®ÐУ©£ºÍ¬ÉÏÃæµÄÀíÓÉÒ»Ñù£¬±ØÐë·Ç³£Ð¡ÐÄ£¡Õâ¸ö×´¿öͬÑùÓÐDZÔڵĵ¼ÖÂËÀËøµÄÇé¿ö¡£

3.²¢·¢¶ÓÁУºÕâ²ÅÊÇ×öͬ²½¹¤×÷µÄºÃÑ¡Ôñ£¬²»ÂÛÊÇͨ¹ýµ÷¶ÈÕϰ­£¬»òÕßÐèÒªµÈ´ýÒ»¸öÈÎÎñÍê³É²ÅÄÜÖ´ÐнøÒ»²½´¦ÀíµÄÇé¿ö¡£

¼ÌÐøÔÚ PhotoManager.m ÉϹ¤×÷£¬ÓÃÏÂÃæµÄʵÏÖÌæ»» photos £º

- (NSArray *)photos
{
__block NSArray *array; // 1
dispatch_sync(self.concurrentPhotoQueue, ^{ // 2
array = [NSArray arrayWithArray:_photosArray]; // 3
});
return array;
}

Õâ¾ÍÊÇÄãµÄ¶Áº¯Êý¡£°´Ë³Ðò¿´¿´±à¹ýºÅµÄ×¢ÊÍ£¬ÓÐÕâЩ£º

1.__block ¹Ø¼ü×ÖÔÊÐí¶ÔÏóÔÚ Block Äڿɱ䡣ûÓÐËü£¬array ÔÚ Block ÄÚ²¿¾ÍÖ»ÊÇÖ»¶ÁµÄ£¬ÄãµÄ´úÂëÉõÖÁ²»ÄÜͨ¹ý±àÒë¡£

2.ÔÚ concurrentPhotoQueue ÉÏͬ²½µ÷¶ÈÀ´Ö´ÐжÁ²Ù×÷¡£

3.½«ÏàÆ¬Êý×é´æ´¢ÔÚ array ÄÚ²¢·µ»ØËü¡£

×îºó£¬ÄãÐèҪʵÀý»¯ÄãµÄ concurrentPhotoQueue ÊôÐÔ¡£ÐÞ¸Ä sharedManager ÒÔ±ãÏñÏÂÃæÕâÑù³õʼ»¯¶ÓÁУº

+ (instancetype)sharedManager
{
static PhotoManager *sharedPhotoManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedPhotoManager = [[PhotoManager alloc] init];
sharedPhotoManager->_photosArray = [NSMutableArray array];

// ADD THIS:
sharedPhotoManager->_concurrentPhotoQueue = dispatch_queue_create("com.selander.GooglyPuff.photoQueue",
DISPATCH_QUEUE_CONCURRENT);
});

return sharedPhotoManager;
}

ÕâÀïʹÓà dispatch_queue_create ³õʼ»¯ concurrentPhotoQueue Ϊһ¸ö²¢·¢¶ÓÁС£µÚÒ»¸ö²ÎÊýÊÇ·´ÏòDNSÑùʽÃüÃû¹ßÀý£»È·±£ËüÊÇÃèÊöÐԵ쬽«ÓÐÖúÓÚµ÷ÊÔ¡£µÚ¶þ¸ö²ÎÊýÖ¸¶¨ÄãµÄ¶ÓÁÐÊÇ´®Ðл¹ÊDz¢·¢¡£

×¢Ò⣺µ±ÄãÔÚÍøÉÏËÑË÷Àý×Óʱ£¬Äã»á¾­³£¿´ÈËÃÇ´«µÝ 0 »òÕß NULL ¸ø dispatch_queue_create µÄµÚ¶þ¸ö²ÎÊý¡£ÕâÊÇÒ»¸ö´´½¨´®ÐжÓÁеĹýʱ·½Ê½£»Ã÷È·ÄãµÄ²ÎÊý×ÜÊǸüºÃ¡£

¹§Ï²¡ª¡ªÄãµÄ PhotoManager µ¥ÀýÏÖÔÚÊÇḬ̈߳²È«µÄÁË¡£²»ÂÛÄãÔں䦻òÔõÑù¶Á»òдÄãµÄÕÕÆ¬£¬Äã¶¼ÓÐÕâÑùµÄ×ÔÐÅ£¬¼´Ëü½«ÒÔ°²È«µÄ·½Ê½Íê³É£¬²»»á³öÏÖÈκξªÏÅ¡£

   
2081 ´Îä¯ÀÀ       32
 
Ïà¹ØÎÄÕÂ

ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖÓë̽ÌÖ
AndroidÊÖ»ú¿ª·¢£¨Ò»£©
 
Ïà¹ØÎĵµ

Android_UI¹Ù·½Éè¼Æ½Ì³Ì
ÊÖ»ú¿ª·¢Æ½Ì¨½éÉÜ
androidÅÄÕÕ¼°ÉÏ´«¹¦ÄÜ
Android½²ÒåÖÇÄÜÊÖ»ú¿ª·¢
Ïà¹Ø¿Î³Ì

Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
Androidϵͳ¿ª·¢
AndroidÓ¦Óÿª·¢
ÊÖ»úÈí¼þ²âÊÔ
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

androidÈË»ú½çÃæÖ¸ÄÏ
AndroidÊÖ»ú¿ª·¢£¨Ò»£©
AndroidÊÖ»ú¿ª·¢£¨¶þ£©
AndroidÊÖ»ú¿ª·¢£¨Èý£©
AndroidÊÖ»ú¿ª·¢£¨ËÄ£©
iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖ̽ÌÖ
ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
ÊÖ»úÈí¼þ×Ô¶¯»¯²âÊÔÑо¿±¨¸æ


Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
AndroidÓ¦Óÿª·¢
Androidϵͳ¿ª·¢
ÊÖ»úÈí¼þ²âÊÔ
ǶÈëʽÈí¼þ²âÊÔ
AndroidÈí¡¢Ó²¡¢ÔÆÕûºÏ


ÁìÏÈIT¹«Ë¾ android¿ª·¢Æ½Ì¨×î¼Ñʵ¼ù
±±¾© Android¿ª·¢¼¼Êõ½ø½×
ijÐÂÄÜÔ´ÁìÓòÆóÒµ Android¿ª·¢¼¼Êõ
ijº½Ì칫˾ Android¡¢IOSÓ¦ÓÃÈí¼þ¿ª·¢
°¢¶û¿¨ÌØ LinuxÄÚºËÇý¶¯
°¬Ä¬Éú ǶÈëʽÈí¼þ¼Ü¹¹Éè¼Æ
Î÷ÃÅ×Ó Ç¶Èëʽ¼Ü¹¹Éè¼Æ