åé¡ãšãããé²åçã«è§£æ±ºããæ¹æ³ãæ€èšããŠãã ããã
self.block = ^{ [self f1]; [self f2]; };
ãã®ã³ãŒãã«ã¯æããã«åé¡ããããŸãã self.blockããŒãåããªããšããããã¯ã¯selfãåç §ããããããªããžã§ã¯ããåé€ããããšã¯ã§ããŸããã LANG_WARN_OBJC_IMPLICIT_RETAIN_SELFãæå¹ã«ãªã£ãŠããå Žåãã³ã³ãã€ã©ãŒã¯èŠåãçºè¡ããŸãã
æ¹å1ïŒ
__weak __typeof(self)weakSelf = self; self.block = ^{ [weakSelf m1]; [weakSelf m2]; };
埪ç°åç §ã®åé¡ã¯è§£æ±ºãããŸããããå¥ã®åé¡ãçºçããŸãã ãããã¯ãåŒã³åºãããæç¹ã§ãweakSelfãªããžã§ã¯ããååšãããããã§ã«ååšããŠããŸããã ãªããžã§ã¯ããååšããªããªã£ãå ŽåãweakSelf == nilãm1ãm2ã¯åŒã³åºãããŸããããã¹ãŠãæ£åžžã§ããããã«èŠããŸãã ãã ããm1ãåŒã³åºããæç¹ã§ãªããžã§ã¯ãã¯ãŸã ååšããŠããã®ã«ãm2ãåŒã³åºããæç¹ã§ãªããžã§ã¯ããååšããªããªãããšããããŸãã ãã®å Žåãm1ãåŒã³åºãããŸãããm2ã¯åŒã³åºãããŸããããã®åäœã¯äºæããªããã®ã§ãããæ£ãããªãå ŽåããããŸãã ããã¯ããã«ãã¹ã¬ããã¢ããªã±ãŒã·ã§ã³ã®ç«¶åç¶æ ã®å ŽåããŸãã¯m1ããªããžã§ã¯ããžã®åç §ã®æ°ãæžãããå ŽåïŒããšãã°ãã³ã¬ã¯ã·ã§ã³ãããªããžã§ã¯ããåé€ããå ŽåïŒã«çºçããå¯èœæ§ããããŸãã CLANG_WARN_OBJC_REPEATED_USE_OF_WEAKããã³CLANG_WARN_OBJC_RECEIVER_WEAKãæå¹ã«ãªã£ãŠããå Žåãã³ã³ãã€ã©ã¯ãã®å Žåã«èŠåãçæããŸãã
æ¹å2ïŒ
__weak typeof(self)weakSelf = self; self.block = ^{ __strong typeof(self)strongSelf = weakSelf; [strongSelf m1]; [strongSelf m2]; };
ãããã¯å ã®ã¡ãœããåŒã³åºãã®äžè²«æ§ã«é¢ããåé¡ã¯è§£æ±ºãããŸããã ããããæ°ãããã®ãæããã«ãªããŸããïŒ
__weak typeof(self)weakSelf = self; self.block = ^{ __strong typeof(self)strongSelf = weakSelf; [strongSelf m1]; [strongSelf m2]; NSAssert(foo == bar, @"Cool assert!") };
NSAssertãRACObserveãªã©ã®ãã¯ãã¯æé»çã«selfã䜿çšããã«ãŒãããã¯ã®åé¡ãçºçããŸãã
æ¹å3ïŒ
__weak typeof(self)weakSelf = self; self.block = ^{ __strong typeof(self)self = weakSelf; [self m1]; [self m2]; NSAssert(foo == bar, @"Cool assert!") };
ããã§ãselfã䜿çšãããã¯ãã®åé¡ã¯è§£æ±ºãããŸããããGCC_WARN_SHADOWãæå¹ã«ãªã£ãŠããå Žåãã³ã³ãã€ã©ãŒã¯èŠåãçæããŸãã
æ¹å4ïŒ
libextobjcã©ã€ãã©ãªã«ã¯ãã³ã³ãã€ã©ã®èŠåãåé€ããã³ãŒããå°ãç°¡ç¥åãããã¯ã@weakifyããã³@stongifyããããŸãã
@weakify(self); // self __weak self.block = ^{ @strongify(self); // self __strong [self m1]; [self m2]; NSAssert(foo == bar, @"Cool assert!") };
ããã¯ã»ãŒæé©ãªãœãªã¥ãŒã·ã§ã³ã§ãããããã§ãããã€ãã®æ¬ ç¹ããªãããã§ã¯ãããŸããã@ weakifyãš@strongifyãé©åãªå Žæã«é 眮ããããšãå¿ããªãã§ãã ããã @weakifyã®åŸã«selfã䜿çšããŠãå®å šã§ãããã³ã³ãã€ã©ã¯èŠåãçºè¡ããå ŽåããããŸãã
åæã«ã匷ããªã³ã¯ã«ãã£ãŠèª€ã£ãŠãããã¯å ã®èªå·±ããã£ããã£ããå¯èœæ§ããŸã ãããŸãã
@weakify(self); // self __weak self.block = ^{ @strongify(self); // self __strong [self m]; NSLog(@"Ivar value form object: %@", _ivar); // self _ivar NSAssert(foo == bar, @"Cool assert!") };
ãããåé¿ããã«ã¯ãããããã£ïŒself.ivarïŒãä»ããã¢ã¯ã»ã¹ã®ã¿ã䜿çšãããããªãŒããŒã©ã€ããããselfãæ瀺çã«äœ¿çšããå¿ èŠããããŸãã
@weakify(self); // self __weak self.block = ^{ @strongify(self); // self __strong [self m]; NSLog(@"Ivar value form object: %@", self->_ivar); // self _ivar NSAssert(foo == bar, @"Cool assert!") };
selfã¯nilã§ããå¯èœæ§ããããself-> _ ivarã®æ瀺çãªéæ¥åç §ã¯ã¯ã©ãã·ã¥ãåŒãèµ·ããããšã«æ³šæããŠãã ããã
ããããã¹ãŠã®åé¡ãèãããšãã¢ã€ãã¢ã¯ãèªå·±ã§ã¯ãªãããããã¯èªäœã次ã®ããã«å€æŽãããã¯ããæžãããšããçãŸããŸããã
- @weakifyã®å Žåã®ããã«ããããã¯ã®ã¹ã³ãŒãå€ã®selfã¯å€æŽãã¹ãã§ã¯ãããŸãã
- NSAssertãä»ã®ãã¯ãã§ã®é©ããé¿ããããã«ãselfãããã¯å ã¯selfãšåŒã°ããã¹ãã§ã
- ãããã¯ãåŒã³åºããããŸã§ãselfãæããªããžã§ã¯ãã¯åŒ±ããªã³ã¯ã«ãã£ãŠä¿åããããããã¯ãåŒã³åºããããšã匷ãåç §ã«ãã£ãŠä¿åãããŸã
- å¯èœã§ããã°ããã¯ãã¯ã_ivarãä»ããŠæé»çã«èªåããã£ããã£ãããããã¯ãèŠã€ããã®ã«åœ¹ç«ã¡ãŸãã
- ãã¹ãŠã®åãã§ãã¯ã¯ããã¯ããªãã§åäœããã¯ãã§ã
- ãã®ãã¯ãã䜿çšãããšãã«ã³ãŒãã®å€æŽãæå°éã«æãã
- å®è¡æã®ãªãŒããŒãããã¯æå°éã«æããå¿ èŠããããŸã
ãã¯ãã¯Pythonã®ãã³ã¬ãŒã¿é¢æ°ã®ããã«åäœããå ¥åãšããŠãããã¯ãåãå ¥ãããã©ã¡ãŒã¿ãŒãšæ»ãå€ã§äºææ§ã®ããæ°ããã©ãããŒãããã¯ã«ã©ããããå¿ èŠããããŸãã ããšãã°ããããã¯ãèããŸãïŒ
self.block = ^(NSObject *obj) { NSLog(@"%@ %@", [self description], obj); return 0; };
æ¹å1ã®ã³ãŒããšåæ§ã«ãselfã匱ããªã³ã¯ãšããŠãã£ããã£ãããããã«ãããã¯ã®ä¿®æ£ãå§ããŸãããã ãããè¡ãã«ã¯ããã®ããŒã«ã«ãªã³ã¯ã宣èšãããæ°ããã¹ã³ãŒããå¿ èŠã§ãã äœæçŽåŸã«åŒã³åºãããå¿åãããã¯ã¯ããã®ãããªã¹ã³ãŒããšããŠé©ããŠããŸãã
self.block = ^{ __weak typeof(self) weakSelf = self; return ^(NSObject *obj) { NSLog(@"%@ %@", [weakSelf description], obj); return 0; }; }();
ã³ã³ãã€ã©ã¯ãå€éšã®ååã®ãªããããã¯ã®æ»ãå€ã®åãèªåçã«æšæž¬ããŸã;ãã¹ãŠãåå®å šã§ãã
ããã§ãå éšãããã¯ã®æ¬äœå ã§ã®åŒã³åºãæã«ãselfã匷ããªã³ã¯ã«ãªãããã«ãäœããã®æ¹æ³ã§ãããäœæããå¿ èŠããããŸãã ãããè¡ãã«ã¯ããããã¯ã2ã€ã®éšåã«åå²ããå¿ èŠããããŸãã^ïŒNSObject * objïŒåã®å®£èšãšãå®éã«ã¯{...}ã®æ¬äœèªäœã§ãã ãããã¯ã®æ¬äœããã©ã¡ãŒã¿ãŒãªãã®ãããã¯ã«å€æãããã®åŒã³åºããå宣èšã䜿çšããŠäœæãããå¥ã®ãããã¯ã«é 眮ããŸããããã«ãããèªå·±ã匷åãªãªã³ã¯ã«ãªããŸãã
self.block = ^{ __weak typeof(self) weakSelf = self; return ^(NSObject *obj) { __strong typeof(self)self = weakSelf; return ^ (void) { NSLog(@"%@, %@", [self description], obj); return 0; }(); }; }();
äž»ãªããªãã¯ã¯ãå ã®ãããã¯ãåçã®ãããã¯ã«çœ®ãæããããšã§ãããããã¯æé»çã«selfã§ã¯ãªãweakSelfããã£ããã£ããåŒã³åºãæã«strongSelfã«å€æããŸãã
return ^(NSObject *obj) { __weak typeof(self)self = weakSelf; return ^ (void) { NSLog(@"%@, %@", [self description], obj); return 0; }(); };
æ¬è³ªçã«ãšåã
^(NSObject *obj) { NSLog(@"%@ %@", [self description], obj); return 0; };
ãããã£ãŠã1ã€ã®ãããã¯ã§ã¯ãªãã3ã€ã®ãããã¯ãäœæãããŸãã äžçªå€åŽã®ãããã¯ã¯äœæåŸããã«åŒã³åºãããããã ã³ãŒããããã¯è©äŸ¡ãŸãã¯ã¹ããŒãã¡ã³ãåŒæ¡åŒµæ©èœã䜿çšããŠåé€ã§ããŸãã
self.block = ({ __weak typeof(self) weakSelf = self; ^(NSObject *obj) { __strong typeof(self)self = weakSelf; return ^ (void) { NSLog(@"%@, %@", [self description], obj); return 0; }(); }; });
ãã®ããªãã¯ã䜿ããããããã«ããã€ã©ãŒãã¬ãŒãå šäœããã¯ãã§ã©ããããããšãæ®ã£ãŠããŸãã äžè¬çãªã³ãŒãã®ã¿ãæ®ããšã次ã®ããã«ãªããŸãã
({ __weak typeof(self) weakSelf = self; /* */ { __strong typeof(self)self = weakSelf; return ^ (void) { /* */ } (); }; })
æåã®ã¢ã€ãã¢ã¯ã次ã®ããã«åŒã³åºããããã¿ã€ããšããã£ã®2ã€ã®ãã©ã¡ãŒã¿ãŒãæã€ãã¯ããäœæããããšã§ããã
self.block = weakself(^(NSObject *obj), { NSLog(@"%@ %@", [self description], obj); return 0; });
ãã ããæ®å¿µãªãããååŠçäžã«ãã¯ãã¯1è¡ã«å±éãããããããããã¯ã®æ¬äœã®ä»»æã®è¡ã«ãã¬ãŒã¯ãã€ã³ããèšå®ããããšã¯ã§ããŸããã ãããã£ãŠãç§ã¯ãããããªããã°ãªããŸããã§ããïŒ
self.block = weakself(^(NSObject *obj)) { NSLog(@"%@ %@", [self description], obj); return 0; } weakselfend ;
ãã®ãªãã·ã§ã³ã¯ãæ¹å4ã®@ weakify / @strongifyãšåçã§ãã ãã¯ãã³ãŒãïŒ
#define weakself(ARGS) \ ({ __weak typeof(self) _private_weakSelf = self; \ ARGS { \ __strong typeof(_private_weakSelf) self __attribute__((unused)) = _private_weakSelf; \ return ^ (void) { #define weakselfend } (); }; })
ãã¯ããäœæãããšãã®ç®æšã®1ã€ã¯ãivarã«ã¢ã¯ã»ã¹ãããšãã«èªå·±ã®æé»çãªãã£ããã£ãã身ãå®ãããšã§ããã æ®å¿µãªãããã³ã³ãã€ã«æã«ãããè¡ãæ¹æ³ã¯æãã€ããŸããã§ããã å¯äžã®ãªãã·ã§ã³ã¯ããããã¯ãäœæãããšãã«ããŒãžã§ã³ããããã°ããassert / logã§ãïŒãã§ãã¯ãæ©èœãããããã«ãããã¯ãäœæããã ãã§ãåŒã³åºãå¿ èŠã¯ãããŸããïŒã ããã§ããã£ããã£ãããããã¯ãšãªããžã§ã¯ãã«å¯Ÿããã¡ã¢ãªç®¡çã®ä»çµã¿ãæãåºããŠãã ããã ãããã¯ã«ã¯3ã€ã®ã¿ã€ãããããŸãã
- NSGlobalBlock-ãœãŒã¹ã³ãŒããã¡ã€ã«ã®ãããã¬ãã«ã§äœæããããããã¯ã¯ãã¡ã¢ãªç®¡çã®èŠ³ç¹ããã¯åºæ¬çã«é¢æ°ãšåãã§ããã¹ã³ãŒãå ã®å€æ°ã¯ãã®ããã«ãšããµã€ãã£ã³ã°ã§ã¯ãªããèå³ããããŸããã
- NSStackBlockã¯ãäœæãããä»ã®ãã¹ãŠã®ãããã¯ã®åæåã§ãããããã¯ã¹ã¿ãã¯äžã«äœæãããŸãããã£ããã£ãããªããžã§ã¯ãã®åç §ã«ãŠã³ãã¯å¢å ããŸããããã®ãããªãããã¯ã®æå¹æéã¯ãã¬ãã·ã«ã«ã¹ã³ãŒãã®å€æ°ã®æå¹æé以äžã§ãã
- NSMallocBlockã¯ãcopy / Block_copyã®æ瀺çãªåŒã³åºãã«ãã£ãŠããŸãã¯ã³ã³ãã€ã©ãŒã«ãã£ãŠæé»çã«ããŒãã«ç§»æ€ãããNSStackBlockã§ãã ã³ã³ãã€ã©ãŒãæé»çã«Block_copyãæ¿å ¥ããã±ãŒã¹ã®1ã€ã¯ãé¢æ°/ãããã¯ã®çµæãšããŠã®ãããã¯ã®æ»ãã§ãã NSStackBlockãNSMallocBlockã«å€æããæç¹ã§ããããã¯ãã¹ã³ãŒãå ã§ãã£ããã£ãããªããžã§ã¯ãã®åç §ã«ãŠã³ããå¢å ããŸãã
ãããã£ãŠããããã¯ãselfãžã®åŒ·åãªãªã³ã¯ããã£ããã£ããŠãããã©ããã確èªããã«ã¯ããããã¯ãããŒãã«è»¢éãããåãšåŸã«ãåç §ã«ãŠã³ã¿ãŒãselfãšæ¯èŒããå¿ èŠããããŸãã ã«ãŠã³ã¿ãŒãå¢å ããå Žåããããã¯ã¯åŒ·åãªãªã³ã¯ã«ãã£ãŠèªå·±ããã£ããã£ããŠããŸãã selfãžã®åç §ã®ã«ãŠã³ã¿ãŒã¯ããŒããžã®ãããã¯è»¢éäžã«ä»ã®ã¹ã¬ããããå€æŽãããå¯èœæ§ãããããããã®ãã§ãã¯ã¯100ïŒ ã®ã±ãŒã¹ã§ã¯ä¿¡é Œã§ããŸããããéåžžã®ããã°ã©ã ã§ã¯ãã®ç¶æ³ã¯èµ·ããããã«ãªãããããã°ã¢ã»ã³ããªã«éåžžã«é©ããŠããŸãã
å ã«retainCountã¡ãœããã䜿çšããŠãªããžã§ã¯ãããåç §ã«ãŠã³ããååŸããããšãã§ããŸãããARCã§ã¯äœ¿çšã§ããªããªããŸããããCFGetRetainCountã¯åŒãç¶ãããªãŒããªããžã§æ©èœããŸãã æ£ããå Žæã«selfãã©ã¡ãŒã¿ãæå®ããŠãã®é¢æ°ã®åŒã³åºããæ¿å ¥ããçµæãæ¯èŒããã ãã§ãã
self.block = {( __weak typeof(self) weakSelf = self; // self ^(NSObject *obj) { __strong typeof(self)self = weakSelf; return ^ (void) { NSLog(@"%@, %@", [self description], obj); return 0; }(); }; }) // . statement expression
åé¡ã¯ãã¹ããŒãã¡ã³ãåŒã®çµæããã®æåŸã®è¡ã§ããããšã§ãã ãã®åäœã¯ã宣èšã®çŽåŸã«åŒã³åºãããå¿åãããã¯ã«äŒŒãŠããŸãã ã¹ããŒãã¡ã³ãåŒã®æåŸã®è¡ã¯ãããã¯ã®å®£èšã§ããããããã®ãããã¯ãæå¹ãªãŸãŸã§ããããã«ãã³ã³ãã€ã©ã¯ãããããŒãã«è»¢éããŸãã ã¹ããŒãã¡ã³ãåŒå ã®ããŒã«ã«å€æ°ã«selfã®CFGetRetainCountã®åŒã³åºããä¿åã§ããããšãããããã¹ããŒãã¡ã³ãåŒã®æåŸã®è¡ã®åŸã«CFGetRetainCountã®2åç®ã®åŒã³åºããè¡ãå¿ èŠããããŸãã C ++ã®å Žåãã¹ã¿ãã¯äžã«ãªããžã§ã¯ããäœæã§ããŸãããªããžã§ã¯ããã¹ãã©ã¯ã¿ã§ã¯ãå¿ èŠãªãã¹ãŠã®åŠçãå®è¡ã§ããŸãããã¹ãã©ã¯ã¿ã¯ã¹ããŒãã¡ã³ãåŒã®æåŸã®è¡ã®åŸã«åŒã³åºãããããã§ãã 幞ããclangã¯gcc-extensionããµããŒãããŠããŸããããã«ãããå€æ°ãã¹ã³ãŒããé¢ããç¬éã«åŒã³åºãããã¹ã¿ãã¯äžã®å€æ°ã«å¯ŸããŠã¯ãªãŒã³ã¢ããé¢æ°ïŒãã¹ãã©ã¯ã¿ã®ã¢ããã°ïŒãèšå®ã§ããŸãã libextobjcã®@onExitãã¯ãã¯ããã®æ¡åŒµæ©èœãéããŠæ©èœããŸãã
åç §ã«ãŠã³ã¿ãŒã®æ€èšŒãå®è£ ããã«ã¯ãè¿œå ã®æ§é ãå¿ èŠã§ãã
struct RefCountCheckerData { CFTypeRef weakSelf; NSUInteger refCountBefore; };
ãããŠãã¯ãªãŒã³ã¢ãããšããŠè«æ±ãããæ©èœã
static inline void vbr_CheckRefCountForWeakSelf(struct RefCountCheckerData *data) { const NSInteger refCountAfter = CFGetRetainCount(data->weakSelf); const NSInteger countOfSelfRefInBlock = refCountAfter - data->refCountBefore; if (countOfSelfRefInBlock > 0) { raise(SIGPIPE); } }
ã¹ã¿ãã¯äžã«æ§é ãäœæããã¯ãªãŒã³ã¢ããé¢æ°ãèšå®ããweakSelfãžã®ãã€ã³ã¿ãŒãšãã®åç §ã®æ°ãåæåããŸãã Cleanupé¢æ°ã¯ãå€æ°_private_refCountCheckerDataãã¹ã³ãŒãããåºããšãã«åŒã³åºããããã®æç¹ã§ãããã¯ã¯æ¢ã«ããŒãå ã«ãããŸãã
self.block = {( __weak typeof(self) weakSelf = self; __attribute__((cleanup(vbr_CheckRefCountForWeakSelf), unused)) struct RefCountCheckerData _private_refCountCheckerData = { .weakSelf = (__bridge CFTypeRef)self, .refCountBefore = CFGetRetainCount((__bridge CFTypeRef)self), }; ^(NSObject *obj) { __strong typeof(self)self = weakSelf; return ^ (void) { NSLog(@"%@, %@", [self description], obj); return 0; }(); }; });
ãã®ããŒãžã§ã³ã®ãã¯ãã§ã¯ãself.block = ^ {NSLogïŒ@ "ïŒ d"ã_ivarIntegerïŒ;ãªã©ã®ããã«ãselfãä»ããã«ivarã«ã¢ã¯ã»ã¹ããããšãããšããããã¬ã®ãã¬ãŒã¯ãã€ã³ããæ©èœããŸãã };
ãã¯ãã®æçµããŒãžã§ã³ãæ瀺ããåã«ãææ°ã®ããããªå€èŠ³ã«ããå¿ èŠããããŸãã ObjCã¯ãèšèªããŒã¯ãŒãã®ããã«ã@ã§å§ãŸããã¯ããäœæããã®ãæµè¡ããŠããŸããããšãã°ã@ strongifyã@ onExitã§ãã ãã ããããªããã»ããµã§ã¯ããã¯ãåã®äžéšãšããŠ@ã䜿çšã§ããŸããã extobjcã¯ããã¯ãautoreleasepool {}ãŸãã¯try {} catch ïŒ...ïŒ{}ã®å é ã§æ¿å ¥ã䜿çšããŸãããã®ããã@èšå·ã¯tryãŸãã¯autoreleasepoolã®ããããã«åºå®ãããŸãã ãã¯ããå±éãããåŸãäžå¿ èŠãªç©ºã®autoreleasepoolãŸãã¯try catchãã³ãŒãã«è¡šç€ºãããŸããã誰ããããæ°ã«ããŸããã ãã ããweakselfã®çµæã¯åŒã§ãããåŒã«ã¯æåã«@autoreleasepool try {} catch ïŒ...ïŒ{}ãå«ããããšãã§ããªãããããã®ã¢ãããŒãã¯weakselfãã¯ãã§ã¯æ©èœããŸããã
self.block = @weakself(^(NSObject *obj)) { NSLog(@"%@ %@", [self description], obj); return 0; } @weakselfend ;
Cã®è€éãªåŒã«é¢ããŠã¯ãäžé æŒç®åãæåã«æãæµ®ãã³ãŸãã ãããé©çšããæ¹æ³ãç解ããããšã¯æ®ã£ãŠããŸãã ãã®ãããªããšãæžãããã«ç§ãæåã«æãã€ããã®ã¯ïŒself.block = @ 1ïŒ / *ããã«ãããã¯ã³ãŒã* /ïŒnil;
ãããè¡ãã«ã¯ã1ãè¿œå ããŸããïŒ æåã«åŒ±è ã§ãããnil; weakselfendã®çµããã«ã ããããself.block = 1ïŒ / *ããã«ãããã¯ã³ãŒã* /ïŒnil; ãŸã£ããæ£ããè¡šçŸãªã®ã§ã@ weakselfãšweakselfãæ©èœããŸãã
ãªãã·ã§ã³self.block = @ []ïŒ / *ããã«ãããã¯ã³ãŒã* /ïŒnil; @ãªãã§@weakselfã䜿çšããããšã¯ã§ããŸããããéã¢ã»ã³ãã©ããã§ãã¯ããåŸããªããã£ãã€ã¶ã空ã®é åã®äœæãã¹ããŒããªãããšãå€æããŸãããããã¯å®è¡æã®äœåãªãªãŒããŒãããã§ãã
æåŸã«ãObjCã§æååãªãã©ã«é£çµæ©èœã䜿çšãããšããã¢ã€ãã¢ãçãŸããŸããã
const char *s0 = "ABC" "DEF"; // C- "ABCDEF" NSString *s1 = @"ABC" @"DEF"; // ObjC- @"ABCDEF" NSString *s2 = @"ABC" "DEF"; // ObjC- @"ABCDEF" NSString *s3 = "ABC" @"DEF"; //
ãããã£ãŠããã¯ãã®æçµããŒãžã§ã³ïŒ
#define weakself(ARGS) \ "weakself should be called as @weakself" @"" ? \ ({ __weak typeof(self) _private_weakSelf = self; \ ARGS { \ __strong typeof(_private_weakSelf) self __attribute__((unused)) = _private_weakSelf; \ return ^ (void) { #define weakselfnotnil(ARGS) \ "weakself should be called as @weakself" @"" ? \ ({ __weak typeof(self) _private_weakSelf = self; \ ARGS { \ __strong typeof(_private_weakSelf) self __attribute__((unused)) = _private_weakSelf; \ return ^ (void) { if (self) #define weakselfend \ try {} @finally {} } (); }; \ }) : nil
@weakselfnotnilã¯ããããã¯ãåŒã³åºããããŸã§ã«selfããã§ã«åé€ãããŠããå Žåããããã¯ãåŒã³åºãããªããšããç¹ã§ç°ãªããŸãã ãããã¯ã«æ»ãå€ããªãå Žåã«ã®ã¿é©ããŠããŸããããã§ãªãå Žåãèªå·±ãæ¢ã«åé€ãããŠããå Žåã«äœãè¿ãããæ確ã§ã¯ãããŸããã æ瀺çãªèªå·±éåç §ãéããŠäž»ã«ivarãå®å šã«äœ¿çšããããã«äœæãããŸããã
self.block = @weakselfnotnil(^) { NSLog(@"%d", self->_ivar); } @weakselfend;
æ§èœ
ããã§ã¯ãããã©ãŒãã³ã¹ã«ã€ããŠããŸãå¿é ããå¿ èŠã¯ãããããªãã§ãããããªãŒããŒãããã¯ããã»ã©å€ããªãã¯ãã§ãã ãã¯ãã®å é ã«@ãè¿œå ããããªãã¯ã¯ããªããã£ãã€ã¶ãŒã«ãã£ãŠå®å šã«ã¹ããŒãããŸãã è¿œå ã®ãŠããããåŒã³åºããªãŒããŒãããã«ãããäºæ ã¯ããèå³æ·±ããã®ã«ãªããŸãã ãªãŒããŒãããã®ç¶æ³ã確èªããã«ã¯ãlibextobjcã®ãã¯ããšweakselfã䜿çšãã2ã€ã®ã±ãŒã¹ãæ€èšããŸãã
- (void)m1 { @weakify(self); self.block = ^(NSObject * obj) { @strongify(self); NSLog(@"%@", [self description]); return 0; }; } - (void)m2 { self.block = @weakself(^(NSObject * obj)) { NSLog(@"%@", [self description]); return 0; } @weakselfend; }
-O3ã§åéããHooperã§éããäž¡æ¹ã®ã±ãŒã¹ã®æ¬äŒŒã³ãŒãã調ã¹ãŸã
function -[ViewController m1] { asm{ vst1.64 {d8, d9, d10, d11}, [r4:128]! }; asm{ vst1.64 {d12, d13, d14, d15}, [r4:128] }; r1 = *_NSConcreteStackBlock; *((sp - 0x40 & !0xf) - 0x50) = r1; var_4 = 0xc2000000; var_24 = ((sp - 0x40 & !0xf) - 0x50) + 0x14; asm{ stm.w r5, {r1, r2, r3} }; r5 = [r0 retain]; objc_initWeak(var_24, r5); [r5 release]; r0 = *__objc_personality_v0; r1 = *0xac24; var_52 = r0; var_56 = GCC_except_table0; var_60 = &var_12; var_68 = (sp - 0x40 & !0xf) - 0x50; var_64 = (r1 | 0x1) + 0xabc4; var_32 = 0x1; [r5 setBlock1:(sp - 0x40 & !0xf) - 0x50]; objc_destroyWeak(var_24); r0 = _Unwind_SjLj_Unregister(&var_28); asm{ vld1.64 {d8, d9, d10, d11}, [r4:128]! }; asm{ vld1.64 {d12, d13, d14, d15}, [r4:128] }; Pop(); Pop(); Pop(); return r0; } function ___20-[ViewController m1]_block_invoke { r4 = objc_loadWeakRetained(r0 + 0x14); r0 = [r4 description]; r5 = [r0 retain]; NSLog(@"%@", r5); [r5 release]; [r4 release]; return 0x0; } function -[ViewController m2] { r4 = r0; r0 = *_NSConcreteStackBlock; *(sp - 0x18) = r0; var_4 = 0xc2000000; asm{ stm.w r3, {r0, r1, r2} }; objc_initWeak((sp - 0x18) + 0x14, r4); r5 = objc_retainBlock(sp - 0x18); objc_destroyWeak((sp - 0x18) + 0x14); [r4 setBlock1:r5]; r0 = [r5 release]; return r0; } function ___20-[ViewController m2]_block_invoke { r4 = objc_loadWeakRetained(r0 + 0x14); r0 = [r4 description]; r5 = [r0 retain]; NSLog(@"%@", r5); [r5 release]; [r4 release]; return 0x0; }
weakselfã¯@ weakify / strongifyãããå¹æçã§ãããå éšã®è¿œå ãããã¯ã¯å®å šã«ã€ã³ã©ã€ã³ã§ããã_block_invokeã¯ã©ã¡ãã®å Žåãåãããã«èŠããŸãã ãããã_Unwind_SjLj_Unregisterã«èŠãããããã«ãextobjcããã¯ãã®å é ã§@ããé£ã¹ããæ¹æ³ã¯ãç¡é§ãªã©ã³ã¿ã€ã äŸå€åŠçã³ãŒããè¿œå ããŸãã
-Osã§ã³ã³ãã€ã«ãããšããã¹ãŠãããã»ã©è¯ããªãããããã¯ã¯ã€ã³ã©ã€ã³ã§ã¯ãªãã1ã€ã®_block_invokeã®ä»£ããã«2ã€ãçæãããŸã
function ___20-[ViewController m2]_block_invoke { r0 = objc_loadWeakRetained(r0 + 0x14); r1 = *_NSConcreteStackBlock; *(sp - 0x18) = r1; var_4 = 0xc2000000; asm{ stm.w r4, {r1, r2, r3} }; var_20 = r0; r4 = [r0 retain]; r5 = ___20-[ViewController m2]_block_invoke_2(sp - 0x18); [var_20 release]; [r4 release]; r0 = r5; return r0; } function ___20-[ViewController m2]_block_invoke_2 { r0 = *(r0 + 0x14); r0 = [r0 description]; r4 = [r0 retain]; NSLog(@"%@", r4); [r4 release]; return 0x0; }
æ®å¿µãªãããclangã§ã¯always_inlineå±æ§ããããã¯ã«è¿œå ããããšã¯ãŸã èš±å¯ãããŠããŸããã
Xcodeã®å®å šãªãœãŒã¹ã³ãŒããšãªãŒãã³ã³ããªãŒãã¯ãã¡ãã§ãã