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

1Ôª 10Ôª 50Ôª





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



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
iOS¶àÏ̵߳½µ×²»°²È«ÔÚÄÄÀ
 
À´Ô´£ºMrPeak ·¢²¼ÓÚ£º 2017-4-26
  2094  次浏览      27
 

iOS¶àḬ̈߳²È«µÄ¸ÅÄîÔÚºÜ¶àµØ·½¶¼»áÓöµ½£¬ÎªÊ²Ã´²»°²È«£¬²»°²È«ÓÖ¸ÃÔõôȥ¶¨Ò壬ÆäʵÊǸöÖµµÃÉµÄ»°Ìâ¡£

¹²Ïí״̬£¬¶àÏ̹߳²Í¬·ÃÎÊij¸ö¶ÔÏóµÄproperty£¬ÔÚiOS±à³ÌÀïÊÇºÜÆÕ±éµÄʹÓó¡¾°£¬ÎÒÃǾʹÓPropertyµÄ¶àḬ̈߳²È«ËµÆð¡£

Property

µ±ÎÒÃÇÌÖÂÛproperty¶àḬ̈߳²È«µÄʱºò£¬ºÜ¶àÈ˶¼ÖªµÀ¸øproperty¼ÓÉÏatomic attributeÖ®ºó£¬¿ÉÒÔÒ»¶¨³Ì¶ÈµÄ±£Õ϶àḬ̈߳²È«£¬ÀàËÆ£º

@property (atomic, strong) NSString*                 userName;

ÊÂÇ鲢ûÓп´ÉÏÈ¥Õâô¼òµ¥£¬Òª·ÖÎöpropertyÔÚ¶àÏ̳߳¡¾°ÏµıíÏÖ£¬ÐèÒªÏȶÔpropertyµÄÀàÐÍ×öÇø·Ö¡£

ÎÒÃÇ¿ÉÒÔ¼òµ¥µÄ½«property·ÖΪֵÀàÐͺͶÔÏóÀàÐÍ£¬ÖµÀàÐÍÊÇÖ¸primitive type£¬°üÀ¨int, long, boolµÈ·Ç¶ÔÏóÀàÐÍ£¬ÁíÒ»ÖÖÊǶÔÏóÀàÐÍ£¬ÉùÃ÷ΪָÕ룬¿ÉÒÔÖ¸Ïòij¸ö·ûºÏÀàÐͶ¨ÒåµÄÄÚ´æÇøÓò¡£

ÉÏÊö´úÂëÖÐuserNameÃ÷ÏÔÊǸö¶ÔÏóÀàÐÍ£¬µ±ÎÒÃÇ·ÃÎÊuserNameµÄʱºò£¬·ÃÎʵÄÓпÉÄÜÊÇuserName±¾Éí£¬Ò²ÓпÉÄÜÊÇuserNameËùÖ¸ÏòµÄÄÚ´æÇøÓò¡£

±ÈÈ磺

self.userName = @"peak";

ÊÇÔÚ¶ÔÖ¸Õë±¾Éí½øÐи³Öµ¡£¶ø

[self.userName rangeOfString:@"peak"];

ÊÇÔÚ·ÃÎÊÖ¸ÕëÖ¸ÏòµÄ×Ö·û´®ËùÔÚµÄÄÚ´æÇøÓò£¬Õâ¶þÕß²¢²»Ò»Ñù¡£

ËùÒÔÎÒÃÇ¿ÉÒÔ´óÖÂÉϽ«property·ÖΪÈýÀࣺ

·ÖÍêÀàÖ®ºó£¬ÎÒÃÇÐèÒªÃ÷°×ÕâÈýÀàpropertyµÄÄÚ´æÄ£ÐÍ¡£

Memory Layout

µ±ÎÒÃÇÌÖÂÛ¶àḬ̈߳²È«µÄʱºò£¬ÆäʵÊÇÔÚÌÖÂÛ¶à¸öÏß³Ìͬʱ·ÃÎÊÒ»¸öÄÚ´æÇøÓòµÄ°²È«ÎÊÌâ¡£Õë¶Ôͬһ¿éÇøÓò£¬ÎÒÃÇÓÐÁ½ÖÖ²Ù×÷£¬¶Á£¨load£©ºÍд£¨store£©£¬¶ÁºÍдͬʱ·¢ÉúÔÚͬһ¿éÇøÓòµÄʱºò£¬¾ÍÓпÉÄܳöÏÖ¶àÏ̲߳»°²È«¡£ËùÒÔÕ¹¿ªÌÖÂÛ֮ǰ£¬ÏÈÒªÃ÷°×ÉÏÊöÈýÖÖpropertyµÄÄÚ´æÄ£ÐÍ£¬¿ÉÓÃÈçÏÂͼʾ£º

ÒÔ64λϵͳΪÀý£¬Ö¸ÕëNSString*ÊÇ8¸ö×Ö½ÚµÄÄÚ´æÇøÓò£¬int countÊǸö4×Ö½ÚµÄÇøÓò£¬¶ø@¡°Peak¡±ÊÇÒ»¿é¸ù¾Ý×Ö·û´®³¤¶È¶ø¶¨µÄÄÚ´æÇøÓò¡£

µ±ÎÒÃÇ·ÃÎÊpropertyµÄʱºò£¬Êµ¼ÊÉÏÊÇ·ÃÎÊÉÏͼÖÐÈý¿éÄÚ´æÇøÓò¡£

self.userName = @"peak";

ÊÇÐ޸ĵÚÒ»¿éÇøÓò¡£

self.count = 10;

ÊÇÔÚÐ޸ĵڶþ¿éÇøÓò¡£

[self.userName rangeOfString:@"peak"];

ÊÇÔÚ¶ÁÈ¡µÚÈý¿éÇøÓò¡£

²»°²È«µÄ¶¨Òå

Ã÷°×ÁËpropertyµÄÀàÐÍÒÔ¼°ËûÃǶÔÓ¦µÄÄÚ´æÄ£ÐÍ£¬ÎÒÃÇÔÙÀ´¿´¿´²»°²È«µÄ¶¨Òå¡£WikipediaÈçÊÇ˵£º

 A piece of code is thread-safe if it manipulates shared data structures only in 
a manner that guarantees safe execution by multiple threads at the same time

Õâ¶Î¶¨Òå¿´ÆðÀ´»¹ÊÇÓеã³éÏó£¬ÎÒÃÇ¿ÉÒÔ½«¶àÏ̲߳»°²È«½âÊÍΪ£º¶àÏ̷߳ÃÎÊʱ³öÏÖÒâÁÏÖ®ÍâµÄ½á¹û¡£Õâ¸öÒâÁÏÖ®ÍâµÄ½á¹û°üº¬¼¸ÖÖ³¡¾°£¬²»Ò»¶¨ÊÇÖ¸crash£¬ºóÃæÔÙÒ»Ò»·ÖÎö¡£

ÏÈÀ´¿´Ï¶àÏß³ÌÊÇÈçºÎͬʱ·ÃÎÊÄÚ´æµÄ¡£²»¿¼ÂÇCPU cache¶Ô±äÁ¿µÄ»º´æ£¬ÄÚ´æ·ÃÎÊ¿ÉÒÔÓÃÏÂͼ±íʾ£º

´ÓÉÏͼÖпÉÒÔ¿´³ö£¬ÎÒÃÇÖ»ÓÐÒ»¸öµØÖ·×ÜÏߣ¬Ò»¸öÄÚ´æ¡£¼´Ê¹ÊÇÔÚ¶àÏ̵߳Ļ·¾³Ï£¬Ò²²»¿ÉÄÜ´æÔÚÁ½¸öÏß³Ìͬʱ·ÃÎÊÒ»¿éÄÚ´æÇøÓòµÄ³¡¾°£¬ÄÚ´æµÄ·ÃÎÊÒ»¶¨ÊÇͨ¹ýÒ»¸öµØÖ·×ÜÏß´®ÐÐÅŶӷÃÎʵģ¬ËùÒÔÔÚ¼ÌÐøºóÐøÖ®Ç°£¬ÎÒÃÇÏÈÒªÃ÷È·¼¸¸ö½áÂÛ£º

½áÂÛÒ»£ºÄÚ´æµÄ·ÃÎÊʱ´®Ðе쬲¢²»»áµ¼ÖÂÄÚ´æÊý¾ÝµÄ´íÂÒ»òÕßÓ¦ÓõÄcrash¡£

½áÂÛ¶þ£ºÈç¹û¶Áд£¨load or store£©µÄÄڴ泤¶ÈСÓÚµÈÓÚµØÖ·×ÜÏߵij¤¶È£¬ÄÇô¶ÁдµÄ²Ù×÷ÊÇÔ­×ӵģ¬Ò»´ÎÍê³É¡£±ÈÈçbool£¬int£¬longÔÚ64λϵͳϵĵ¥´Î¶Áд¶¼ÊÇÔ­×Ó²Ù×÷¡£

½ÓÏÂÀ´ÎÒÃǸù¾ÝÉÏÃæÈýÖÖpropertyµÄ·ÖÀàÖðÒ»¿´Ï¶àÏ̵߳IJ»°²È«³¡¾°¡£

ÖµÀàÐÍProperty

ÏÈÒÔBOOLÖµÀàÐÍΪÀý£¬µ±ÎÒÃÇÓÐÁ½¸öÏ̷߳ÃÎÊÈçÏÂpropertyµÄʱºò£º

@property (nonatomic, assgin) BOOL    isDeleted;

//thread 1
bool isDeleted = self.isDeleted;

//thread 2
self.isDeleted = false;

Ïß³Ì1ºÍÏß³Ì2£¬Ò»¸ö¶Á(load)£¬Ò»¸öд(store)£¬¶ÔÓÚBOOL isDeletedµÄ·ÃÎÊ¿ÉÄÜÓÐÏȺóÖ®·Ö£¬µ«Ò»¶¨ÊÇ´®ÐÐÅŶӵġ£¶øÇÒÓÉÓÚBOOL´óСֻÓÐ1¸ö×Ö½Ú£¬64λϵͳµÄµØÖ·×ÜÏß¶ÔÓÚ¶ÁдָÁî¿ÉÒÔÖ§³Ö8¸ö×ֽڵij¤¶È£¬ËùÒÔ¶ÔÓÚBOOLµÄ¶ÁºÍд²Ù×÷ÎÒÃÇ¿ÉÒÔÈÏΪÊÇÔ­×ӵģ¬ËùÒÔµ±ÎÒÃÇÉùÃ÷BOOLÀàÐ͵ÄpropertyµÄʱºò£¬´ÓÔ­×ÓÐԵĽǶȿ´£¬Ê¹ÓÃatomicºÍnonatomic²¢Ã»ÓÐʵ¼ÊÉϵÄÇø±ð£¨µ±È»Èç¹ûÖØÔØÁËgetter·½·¨¾ÍÁíµ±±ðÂÛÁË£©¡£

Èç¹ûÊÇintÀàÐÍÄØ£¿

@property (nonatomic, assgin) int    count;

//thread 1
int curCount = self.count;

//thread 2
self.count = 1;

ͬÀíintÀàÐͳ¤¶ÈΪ4×Ö½Ú£¬¶ÁºÍд¶¼¿ÉÒÔͨ¹ýÒ»¸öÖ¸ÁîÍê³É£¬ËùÒÔÀíÂÛÉ϶ÁºÍд²Ù×÷¶¼ÊÇÔ­×ӵġ£´Ó·ÃÎÊÄÚ´æµÄ½Ç¶È¿´nonatomicºÍatomicÒ²²¢Ã»ÓÐÊ²Ã´Çø±ð¡£

atomicµ½µ×ÓÐʲôÓÃÄØ£¿¾ÝÎÒËùÖª£¬Óô¦Óжþ£º

Óô¦Ò»£º Éú³ÉÔ­×Ó²Ù×÷µÄgetterºÍsetter¡£

ÉèÖÃatomicÖ®ºó£¬Ä¬ÈÏÉú³ÉµÄgetterºÍsetter·½·¨Ö´ÐÐÊÇÔ­×ӵġ£Ò²¾ÍÊÇ˵£¬µ±ÎÒÃÇÔÚÏß³Ì1Ö´ÐÐgetter·½·¨µÄʱºò£¨´´½¨µ÷ÓÃÕ»£¬·µ»ØµØÖ·£¬³öÕ»£©£¬Ïß³ÌBÈç¹ûÏëÖ´ÐÐsetter·½·¨£¬±ØÐëÏȵÈgetter·½·¨Íê³É²ÅÄÜÖ´ÐС£¾Ù¸öÀý×Ó£¬ÔÚ32λϵͳÀÈç¹ûͨ¹ýgetter·µ»Ø64λµÄdouble£¬µØÖ·×ÜÏß¿í¶ÈΪ32룬´ÓÄÚ´æµ±ÖжÁÈ¡doubleµÄʱºòÎÞ·¨Í¨¹ýÔ­×Ó²Ù×÷Íê³É£¬Èç¹û²»Í¨¹ýatomic¼ÓËø£¬ÓпÉÄÜ»áÔÚ¶ÁÈ¡µÄÖÐ;ÔÚÆäËûÏ̷߳¢Éúsetter²Ù×÷£¬´Ó¶ø³öÏÖÒì³£Öµ¡£Èç¹û³öÏÖÕâÖÖÒì³£Öµ£¬¾Í·¢ÉúÁ˶àÏ̲߳»°²È«¡£

Óô¦¶þ£ºÉèÖÃMemory Barrier

¶ÔÓÚObjective CµÄʵÏÖÀ´Ëµ£¬¼¸ºõËùÓеļÓËø²Ù×÷×îºó¶¼»áÉèÖÃmemory barrier£¬atomic±¾ÖÊÉÏÊǶÔgetter£¬setter¼ÓÁËËø£¬ËùÒÔÒ²»áÉèÖÃmemory barrier¡£¹Ù·½Îĵµ±íÊöÈçÏ£º

Note: Most types of locks also incorporate a memory barrier to ensure that
any preceding load and store instructions are completed before entering the critical section.

memory barrierÓÐʲôÓô¦ÄØ£¿

memory barrierÄܹ»±£Ö¤ÄÚ´æ²Ù×÷µÄ˳Ðò£¬°´ÕÕÎÒÃÇ´úÂëµÄÊéд˳ÐòÀ´¡£ÌýÆðÀ´Óе㲻¿É˼Ò飬ÊÂʵÊDZàÒëÆ÷»á¶ÔÎÒÃǵĴúÂë×öÓÅ»¯£¬ÔÚËüÈÏΪºÏÀíµÄ³¡¾°¸Ä±äÎÒÃÇ´úÂë×îÖÕ·­Òë³ÉµÄ»úÆ÷Ö¸Áî˳Ðò¡£Ò²¾ÍÊÇ˵ÈçÏ´úÂ룺

self.intA = 0;  //line 1
self.intB = 1; //line 2

±àÒëÆ÷¿ÉÄÜÔÚһЩ³¡¾°ÏÂÏÈÖ´ÐÐline2£¬ÔÙÖ´ÐÐline1£¬ÒòΪËüÈÏΪAºÍBÖ®¼ä²¢²»´æÔÚÒÀÀµ¹ØÏµ£¬ËäÈ»ÔÚ´úÂëÖ´ÐеÄʱºò£¬ÔÚÁíÒ»¸öÏß³ÌintAºÍintB´æÔÚijÖÖÒÀÀµ£¬±ØÐëÒªÇóline1ÏÈÓÚline2Ö´ÐС£

Èç¹ûÉèÖÃpropertyΪatomic£¬Ò²¾ÍÊÇÉèÖÃÁËmemory barrierÖ®ºó£¬¾ÍÄܹ»±£Ö¤line1µÄÖ´ÐÐÒ»¶¨ÊÇÏÈÓÚline2µÄ£¬µ±È»ÕâÖÖ³¡¾°·Ç³£º±¼û£¬Ò»ÔòÊdzöÏÖ±äÁ¿¿çÏ̷߳ÃÎÊÒÀÀµ£¬¶þÊÇÓöÉϱàÒëÆ÷µÄÓÅ»¯£¬Á½¸öÌõ¼þȱһ²»¿É¡£ÕâÖÖ¼«¶ËµÄ³¡¾°Ï£¬atomicȷʵ¿ÉÒÔÈÃÎÒÃǵĴúÂë¸ü¼Ó¶àḬ̈߳²È«Ò»µã£¬µ«ÎÒдiOS´úÂëÖÁ½ñ£¬»¹Î´Óöµ½¹ýÕâÖÖ³¡¾°£¬½Ï´óµÄ¿ÉÄÜÐÔÊDZàÒëÆ÷ÒѾ­×ã¹»´ÏÃ÷£¬ÔÚÎÒÃÇÐèÒªµÄµØ·½ÉèÖÃmemory barrierÁË¡£

ÊDz»ÊÇʹÓÃÁËatomic¾ÍÒ»¶¨¶àḬ̈߳²È«ÄØ£¿ÎÒÃÇ¿ÉÒÔ¿´¿´ÈçÏ´úÂ룺

@property (atomic, assign)    int       intA;

//thread A
for (int i = 0; i < 10000; i ++) {
self.intA = self.intA + 1;
NSLog(@"Thread A: %d\n", self.intA);
}

//thread B
for (int i = 0; i < 10000; i ++) {
self.intA = self.intA + 1;
NSLog(@"Thread B: %d\n", self.intA);
}

¼´Ê¹ÎÒ½«intAÉùÃ÷Ϊatomic£¬×îºóµÄ½á¹ûÒ²²»Ò»¶¨»áÊÇ20000¡£Ô­Òò¾ÍÊÇÒòΪself.intA = self.intA + 1;²»ÊÇÔ­×Ó²Ù×÷£¬ËäÈ»intAµÄgetterºÍsetterÊÇÔ­×Ó²Ù×÷£¬µ«µ±ÎÒÃÇʹÓÃintAµÄʱºò£¬Õû¸öÓï¾ä²¢²»ÊÇÔ­×ӵģ¬ÕâÐи³ÖµµÄ´úÂëÖÁÉÙ°üº¬¶ÁÈ¡(load)£¬+1(add)£¬¸³Öµ(store)Èý²½²Ù×÷£¬µ±Ç°Ïß³ÌstoreµÄʱºò¿ÉÄÜÆäËûÏß³ÌÒѾ­Ö´ÐÐÁËÈô¸É´ÎstoreÁË£¬µ¼ÖÂ×îºóµÄֵСÓÚÔ¤ÆÚÖµ¡£ÕâÖÖ³¡¾°ÎÒÃÇÒ²¿ÉÒÔ³ÆÖ®Îª¶àÏ̲߳»°²È«¡£

Ö¸ÕëProperty

Ö¸ÕëPropertyÒ»°ãÖ¸ÏòÒ»¸ö¶ÔÏ󣬱ÈÈ磺

@property (atomic, strong) NSString*                 userName;

ÎÞÂÛiOSϵͳÊÇ32λϵͳ»¹ÊÇ64룬һ¸öÖ¸ÕëµÄÖµ¶¼ÄÜͨ¹ýÒ»¸öÖ¸ÁîÍê³Éload»òÕßstore¡£µ«ºÍprimitive type²»Í¬µÄÊÇ£¬¶ÔÏóÀàÐÍ»¹ÓÐÄÚ´æ¹ÜÀíµÄÏà¹Ø²Ù×÷¡£ÔÚMRCʱ´ú£¬ÏµÍ³Ä¬ÈÏÉú³ÉµÄsetterÀàËÆÈçÏ£º

- (void)setUserName:(NSString *)userName {
if(_uesrName != userName) {
[userName retain];
[_userName release];
_userName = userName;
}
}

²»½ö½öÊǸ³Öµ²Ù×÷£¬»¹»áÓÐretain£¬releaseµ÷Óá£Èç¹ûpropertyΪnonatomic£¬ÉÏÊöµÄsetter·½·¨¾Í²»ÊÇÔ­×Ó²Ù×÷£¬ÎÒÃÇ¿ÉÒÔ¼ÙÉèÒ»ÖÖ³¡¾°£¬Ïß³Ì1ÏÈͨ¹ýgetter»ñÈ¡µ±Ç°_userName£¬Ö®ºóÏß³Ì2ͨ¹ýsetterµ÷ÓÃ[_userName release];£¬Ïß³Ì1Ëù³ÖÓеÄ_userName¾Í±ä³ÉÎÞЧµÄµØÖ·¿Õ¼äÁË£¬Èç¹ûÔÙ¸øÕâ¸öµØÖ·¿Õ¼ä·¢ÏûÏ¢¾Í»áµ¼ÖÂcrash£¬³öÏÖ¶àÏ̲߳»°²È«µÄ³¡¾°¡£

µ½ÁËARCʱ´ú£¬XcodeÒѾ­ÌæÎÒÃÇ´¦ÀíÁËretainºÍrelease£¬¾ø´ó²¿·ÖʱºòÎÒÃǶ¼²»ÐèҪȥ¹ØÐÄÄÚ´æµÄ¹ÜÀí£¬µ«retain£¬releaseÆäʵ»¹ÊÇ´æÔÚÓÚ×îºóÔËÐеĴúÂëµ±ÖУ¬atomicºÍnonatomic¶ÔÓÚ¶ÔÏóÀàµÄpropertyÉùÃ÷ÀíÂÛÉÏ»¹ÊÇ´æÔÚ²îÒ죬²»¹ýÎÒÔÚʵ¼ÊʹÓõ±ÖУ¬½«NSString*ÉèÖÃΪnonatomicÒ²´ÓδÓöµ½¹ýÉÏÊö¶àÏ̲߳»°²È«µÄ³¡¾°£¬¼«ÓпÉÄÜARCÔÚÄÚ´æ¹ÜÀíÉϵÄÓÅ»¯ÒѾ­½«ÉÏÊö³¡¾°´¦Àí¹ýÁË£¬ËùÒÔÎÒ¸öÈ˾õµÃ£¬Èç¹ûÖ»ÊǶԶÔÏóÀàproperty×öread£¬write£¬atomicºÍnonatomicÔÚ¶àḬ̈߳²È«Éϲ¢Ã»ÓÐʵ¼Ê²î±ð¡£

Ö¸ÕëPropertyÖ¸ÏòµÄÄÚ´æÇøÓò

ÕâÒ»Àà¶àÏ̵߳ķÃÎʳ¡¾°ÊÇÎÒÃǺÜÈÝÒ׳ö´íµÄµØ·½£¬¼´Ê¹ÎÒÃÇÉùÃ÷propertyΪatomic£¬ÒÀÈ»»á³ö´í¡£ÒòΪÎÒÃÇ·ÃÎʵIJ»ÊÇpropertyµÄÖ¸ÕëÇøÓò£¬¶øÊÇpropertyËùÖ¸ÏòµÄÄÚ´æÇøÓò¡£¿ÉÒÔ¿´ÈçÏ´úÂ룺

@property (atomic, strong) NSString*                 stringA;

//thread A
for (int i = 0; i < 100000; i ++) {
if (i % 2 == 0) {
self.stringA = @"a very long string";
}
else {
self.stringA = @"string";
}
NSLog(@"Thread A: %@\n", self.stringA);
}

//thread B
for (int i = 0; i < 100000; i ++) {
if (self.stringA.length >= 10) {
NSString* subStr = [self.stringA substringWithRange:NSMakeRange(0, 10)];
}
NSLog(@"Thread B: %@\n", self.stringA);
}

ËäÈ»stringAÊÇatomicµÄproperty£¬¶øÇÒÔÚÈ¡substringµÄʱºò×öÁËlengthÅжϣ¬Ïß³ÌB»¹ÊǺÜÈÝÒ×crash£¬ÒòΪÔÚǰһ¿Ì¶ÁlengthµÄʱºòself.stringA = @"a very long string";£¬ÏÂÒ»¿ÌÈ¡substringµÄʱºòÏß³ÌAÒѾ­½«self.stringA = @"string";£¬Á¢¼´³öÏÖout of boundsµÄException£¬crash£¬¶àÏ̲߳»°²È«¡£

ͬÑùµÄ³¡¾°»¹´æÔÚ¶Ô¼¯ºÏÀà²Ù×÷µÄʱºò£¬±ÈÈ磺

@property (atomic, strong) NSArray*                 arr;

//thread A
for (int i = 0; i < 100000; i ++) {
if (i % 2 == 0) {
self.arr = @[@"1", @"2", @"3"];
}
else {
self.arr = @[@"1"];
}
NSLog(@"Thread A: %@\n", self.arr);
}

//thread B
for (int i = 0; i < 100000; i ++) {
if (self.arr.count >= 2) {
NSString* str = [self.arr objectAtIndex:1];
}
NSLog(@"Thread B: %@\n", self.arr);
}

ͬÀí£¬¼´Ê¹ÎÒÃÇÔÚ·ÃÎÊobjectAtIndex֮ǰ×öÁËcountµÄÅжϣ¬Ïß³ÌBÒÀ¾ÉºÜÈÝÒ×crash£¬Ô­ÒòÒ²ÊÇÓÉÓÚǰºóÁ½ÐдúÂëÖ®¼äarrËùÖ¸ÏòµÄÄÚ´æÇøÓò±»ÆäËûÏß³ÌÐÞ¸ÄÁË¡£

ËùÒÔÄã¿´£¬ÕæÕýÐèÒª²ÙÐĵÄÊÇÕâÒ»ÀàÄÚ´æÇøÓòµÄ·ÃÎÊ£¬¼´Ê¹ÉùÃ÷ΪatomicҲûÓÐÓã¬ÎÒÃÇÆ½³£App³öÏÖĪÃûÆäÃîÄÑÒÔÖØÏֵĶàÏß³Ìcrash¶àÊÇÊôÓÚÕâÒ»À࣬һµ©ÔÚ¶àÏ̵߳ij¡¾°Ï·ÃÎÊÕâÀàÄÚ´æÇøÓòµÄʱºò£¬ÒªÌáÆðÊ®¶þ·ÖµÄСÐÄ¡£ÈçºÎ±ÜÃâÕâÀàcrashºóÃæ»á̸µ½¡£

Property¶àḬ̈߳²È«Ð¡½á£º

¼ò¶øÑÔÖ®£¬atomicµÄ×÷ÓÃÖ»ÊǸøgetterºÍsetter¼ÓÁ˸öËø£¬atomicÖ»Äܱ£Ö¤´úÂë½øÈëgetter»òÕßsetterº¯ÊýÄÚ²¿Ê±Êǰ²È«µÄ£¬Ò»µ©³öÁËgetterºÍsetter£¬¶àḬ̈߳²È«Ö»ÄÜ¿¿³ÌÐòÔ±×Ô¼º±£ÕÏÁË¡£ËùÒÔatomicÊôÐÔºÍʹÓÃpropertyµÄ¶àḬ̈߳²È«²¢Ã»Ê²Ã´Ö±½ÓµÄÁªÏµ¡£ÁíÍ⣬atomicÓÉÓÚ¼ÓËøÒ²»á´øÀ´Ò»Ð©ÐÔÄÜËðºÄ£¬ËùÒÔÎÒÃÇÔÚ±àдiOS´úÂëµÄʱºò£¬Ò»°ãÉùÃ÷propertyΪnonatomic£¬ÔÚÐèÒª×ö¶àḬ̈߳²È«µÄ³¡¾°£¬×Ô¼ºÈ¥¶îÍâ¼ÓËø×öͬ²½¡£

ÈçºÎ×öµ½¶àḬ̈߳²È«£¿

ÌÖÂÛµ½ÕâÀÆäʵÔõô×öµ½¶àḬ̈߳²È«Ò²±È½ÏÃ÷ÀÊÁË£¬¹Ø¼ü×ÖÊÇatomicity£¨Ô­×ÓÐÔ£©£¬Ö»Òª×öµ½Ô­×ÓÐÔ£¬Ð¡µ½Ò»¸öprimitive type±äÁ¿µÄ·ÃÎÊ£¬´óµ½Ò»³¤¶Î´úÂëÂß¼­µÄÖ´ÐУ¬Ô­×ÓÐÔÄܱ£Ö¤´úÂë´®ÐеÄÖ´ÐУ¬Äܱ£Ö¤´úÂëÖ´Ðе½Ò»°ëµÄʱºò£¬²»»áÓÐÁíÒ»¸öÏ߳̽éÈë¡£

Ô­×ÓÐÔÊǸöÏà¶ÔµÄ¸ÅÄËüËùÕë¶ÔµÄ¶ÔÏó£¬Á£¶È¿É´ó¿ÉС¡£

±ÈÈç϶δúÂ룺

if (self.stringA.length >= 10) {
NSString* subStr = [self.stringA substringWithRange:NSMakeRange(0, 10)];
}

ÊÇ·ÇÔ­×ÓÐԵġ£

µ«¼ÓËøÒÔºó£º

//thread A
[_lock lock];
for (int i = 0; i < 100000; i ++) {
if (i % 2 == 0) {
self.stringA = @"a very long string";
}
else {
self.stringA = @"string";
}
NSLog(@"Thread A: %@\n", self.stringA);
}
[_lock unlock];

//thread B
[_lock lock];
if (self.stringA.length >= 10) {
NSString* subStr = [self.stringA substringWithRange:NSMakeRange(0, 10)];
}
[_lock unlock];

Õû¶Î´úÂë¾Í¾ßÓÐÔ­×ÓÐÔÁË£¬¾Í¿ÉÒÔÈÏΪÊǶàḬ̈߳²È«ÁË¡£

ÔÙ±ÈÈ磺

if (self.arr.count >= 2) {
NSString* str = [self.arr objectAtIndex:1];
}

ÊÇ·ÇÔ­×ÓÐԵġ£

¶ø

//thread A
[_lock lock];
for (int i = 0; i < 100000; i ++) {
if (i % 2 == 0) {
self.arr = @[@"1", @"2", @"3"];
}
else {
self.arr = @[@"1"];
}
NSLog(@"Thread A: %@\n", self.arr);
}
[_lock unlock];

//thread B
[_lock lock];
if (self.arr.count >= 2) {
NSString* str = [self.arr objectAtIndex:1];
}
[_lock unlock];

ÊǾßÓÐÔ­×ÓÐԵġ£×¢Ò⣬¶ÁºÍд¶¼ÐèÒª¼ÓËø¡£

ÕâÒ²ÊÇΪʲôÎÒÃÇÔÚ×ö¶àḬ̈߳²È«µÄʱºò£¬²¢²»ÊÇͨ¹ý¸øproperty¼Óatomic¹Ø¼ü×ÖÀ´±£Õϰ²È«£¬¶øÊǽ«propertyÉùÃ÷Ϊnonatomic£¨nonatomicûÓÐgetter£¬setterµÄËø¿ªÏú£©£¬È»ºó×Ô¼º¼ÓËø¡£

ÈçºÎʹÓÃÄÄÖÖËø£¿

iOS¸ø´úÂë¼ÓËøµÄ·½Ê½ÓкܶàÖÖ£¬³£ÓõÄÓУº

@synchronized(token)

NSLock

dispatch_semaphore_t

OSSpinLock

Õ⼸ÖÖËø¶¼¿ÉÒÔ´øÀ´Ô­×ÓÐÔ£¬ÐÔÄܵÄËðºÄ´ÓÉÏÖÁÏÂÒÀ´Î¸üС¡£

ÎÒ¸öÈ˽¨ÒéÊÇ£¬ÔÚ±àдӦÓòã´úÂëµÄʱºò£¬³ýÁËOSSpinLockÖ®Í⣬Äĸö˳ÊÖÓÃÄĸö¡£Ïà½ÏÓÚÕ⼸¸öËøµÄÐÔÄܲîÒ죬´úÂëÂß¼­µÄÕýÈ·ÐÔ¸üÎªÖØÒª¡£¶øÇÒÕ⼸ÕßÖ®¼äµÄÐÔÄܲîÒì¶ÔÓû§À´Ëµ£¬¾ø´ó²¿·Öʱºò¶¼¸ÐÖª²»µ½¡£

µ±È»ÎÒÃÇÒ²»áÓöµ½ÉÙÊý³¡¾°ÐèҪ׷Çó´úÂëµÄÐÔÄÜ£¬±ÈÈç±àдframework£¬»òÕßÔÚ¶àÏ̶߳Áд¹²ÏíÊý¾ÝƵ·±µÄ³¡¾°£¬ÎÒÃÇÐèÒª´óÖÂÁ˽âËø´øÀ´µÄËðºÄµ½µ×ÓжàÉÙ¡£

¹Ù·½ÎĵµÓиöÊý¾Ý£¬Ê¹ÓÃIntel-based iMac with a 2 GHz Core Duo processor and 1 GB of RAM running OS X v10.5²âÊÔ£¬»ñÈ¡mutexÓдó¸Å0.2msµÄËðºÄ£¬ÎÒÃÇ¿ÉÒÔÈÏÎªËø´øÀ´µÄËðºÄ´óÖÂÔÚms¼¶±ð¡£

Atomic Operations

Æäʵ³ýÁ˸÷ÖÖËøÖ®Í⣬iOSÉÏ»¹ÓÐÁíÒ»ÖÖ°ì·¨À´»ñȡԭ×ÓÐÔ£¬Ê¹ÓÃAtomic Operations£¬Ïà±ÈËøµÄËðºÄҪСһ¸öÊýÁ¿¼¶×óÓÒ£¬ÔÚһЩ׷Çó¸ßÐÔÄܵĵÚÈý·½Framework´úÂëÀï¿ÉÒÔ¿´µ½ÕâЩAtomic OperationsµÄʹÓá£ÕâЩatomic operation¿ÉÒÔÔÚ/usr/include/libkern/OSAtomic.hÖв鵽£º

±ÈÈç

_intA ++;

ÊÇ·ÇÔ­×ÓÐԵġ£

¶ø

OSAtomicIncrement32(&(_intA));

ÊÇÔ­×ÓÐԵ쬶àḬ̈߳²È«µÄ¡£

Atomic OperationÖ»ÄÜÓ¦ÓÃÓÚ32λ»òÕß64λµÄÊý¾ÝÀàÐÍ£¬ÔÚ¶àÏß³ÌʹÓÃNSString»òÕßNSArrayÕâÀà¶ÔÏóµÄ³¡¾°£¬»¹ÊǵÃʹÓÃËø¡£

´ó²¿·ÖµÄAtomic Operation¶¼ÓÐOSAtomicXXX£¬OSAtomicXXXBarrierÁ½¸ö°æ±¾£¬Barrier¾ÍÊÇÇ°ÃæÌáµ½µÄmemory barrier£¬ÔÚ¶àÏ̶߳à¸ö±äÁ¿Ö®¼ä´æÔÚÒÀÀµµÄʱºòʹÓÃBarrierµÄ°æ±¾£¬Äܹ»±£Ö¤ÕýÈ·µÄÒÀÀµË³Ðò¡£

¶ÔÓÚÆ½Ê±±àдӦÓòã¶àḬ̈߳²È«´úÂ룬ÎÒ»¹Êǽ¨Òé´ó¼Ò¶àʹÓÃ@synchronized£¬NSLock£¬»òÕßdispatch_semaphore_t£¬¶àḬ̈߳²È«±È¶àÏß³ÌÐÔÄܸüÖØÒª£¬Ó¦¸ÃÔÚǰÕߵõ½³ä·Ö±£Ö¤£¬ÓÌÓÐÓàÁ¦µÄʱºòÔÙÈ¥×·ÇóºóÕß¡£

¾¡Á¿±ÜÃâ¶àÏ̵߳ÄÉè¼Æ

ÎÞÂÛÎÒÃÇд¹ý¶àÉÙ´úÂ룬¶¼±ØÐëÒª³ÐÈ϶àḬ̈߳²È«ÊǸö¸´ÔÓµÄÎÊÌ⣬×÷Ϊ³ÌÐòÔ±ÎÒÃÇÓ¦¸Ã¾¡¿ÉÄܵıÜÃâ¶àÏ̵߳ÄÉè¼Æ£¬¶ø²»ÊÇÈ¥×·Çó¸ßÃ÷µÄʹÓÃËøµÄ¼¼ÄÜ¡£

ºóÃæÎÒ»áдһƪÎÄÕ£¬½éÉܺ¯Êýʽ±à³Ì¼°ÆäºËÐÄ˼Ï룬¼´Ê¹ÎÒÃÇʹÓ÷Ǻ¯ÊýʽµÄ±à³ÌÓïÑÔ£¬±ÈÈçObjective C£¬Ò²Äܼ«´óµÄ°ïÖúÎÒÃDZÜÃâ¶àḬ̈߳²È«µÄÎÊÌâ¡£

×ܽá

iOS϶àÏ̲߳»°²È«µÄ·ÖÎöÖÁ´Ë½áÊøÁË£¬ÈçºÎ±àд¶àḬ̈߳²È«µÄ´úÂ룬˵µ½µ×»¹ÊÇÔÚÓÚ¶Ômemory layoutºÍÔ­×ÓÐÔµÄÀí½â£¬Ò²Ï£ÍûÕâÆªÎÄÕ½«atomicºÍnonatomicµÄÕæÕýÇø±ð½âÊÍÇå³þÁË:)¡£

   
2094 ´Îä¯ÀÀ       27
 
Ïà¹ØÎÄÕÂ

ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶Ë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ÄÚºËÇý¶¯
°¬Ä¬Éú ǶÈëʽÈí¼þ¼Ü¹¹Éè¼Æ
Î÷ÃÅ×Ó Ç¶Èëʽ¼Ü¹¹Éè¼Æ