ããã«ã¡ã¯ååã
iOSåãã®å€åœã®éçºè
ã®ããã°ãèšäºãé·ãéèªãã§ããŸãã å
æ¥ã
ãã€ã¯ã»ã¢ãã·ã¥ãšããéçºè
ããã®èªååç
§ã«ãŠã³ãã«é¢ãã奜å¥å¿ãçã§ããªã詳现ãªèšäºã«åºäŒããŸããã
ãã®èšäºã¯éåžžã«å€§ãããããç§ãäœæãã翻蚳ãããã€ãã®éšåã«åå²ãããªã¹ã¯ããããŸãã ç§ã¯2ã€ã®éšåã§ç¶æããããšèããŠããŸãã
Appleããã®é©æ°ãçºè¡šããŠä»¥æ¥ãèªè
ã¯èªååç
§ã«ãŠã³ãïŒARCïŒã¡ã«ããºã ã«ã€ããŠæžãããšãç§ã«å§ããŠããŸããã æãæ¥ãŸããã æ¬æ¥ã¯ãAppleã®æ°ããã¡ã¢ãªç®¡çã·ã¹ãã ã«ã€ããŠèª¬æããŸãããããã©ã®ããã«æ©èœããã®ãããããèªåã§æ©èœãããæ¹æ³ã§ãã
ã³ã³ã»ããClang Static Analyzerã¯ãã³ãŒãå
ã®ã¡ã¢ãªç®¡çãšã©ãŒãèŠã€ããã®ã«éåžžã«äŸ¿å©ãªããŒã«ã§ãã ããªããšç§ã䌌ãŠããå Žåãã¢ãã©ã€ã¶ãŒã®åºåãèŠãŠããã¢ãã©ã€ã¶ãŒããšã©ãŒãæ€åºããå Žåããªãç§ã§ã¯ãªãä¿®æ£ãã¹ãã§ã¯ãªããããšèããŸãã
èŠããã«-ããã¯ARCã®æ¬è³ªã§ãã ã¡ã¢ãªç®¡çã«ãŒã«ã¯ã³ã³ãã€ã©ã«çµã¿èŸŒãŸããŠããŸãã ããããéçºè
ããšã©ãŒãèŠã€ããã®ãå©ããããã«ãããã䜿çšãã代ããã«ãARCã¡ã«ããºã ã¯åã«å¿
èŠãªåŒã³åºããæ¿å
¥ããŸãã ãããŠããã ãã§ãã
ARCã¡ã«ããºã ã¯ãã¬ããŒãžã³ã¬ã¯ã¿ãŒãšæåã¡ã¢ãªç®¡çã®éã®ã©ããã«ãããŸãã ã¬ããŒãžã³ã¬ã¯ã¿ãŒãšåæ§ã«ãARCã¯éçºè
ã
retain / release / autoreleaseåŒã³åºããèšè¿°
ããå¿
èŠããªãã
ãŸã ã ãã ããã¬ããŒãžã³ã¬ã¯ã¿ãšã¯ç°ãªããARCã¯ã«ãŒãã
ä¿æããããã«ãããªãæ¹æ³ã§ãåå¿ããŸããã çžäºã«åŒ·ããªã³ã¯ãæã€2ã€ã®ãªããžã§ã¯ãã¯ã誰ãåç
§ããŠããªãå Žåã§ããARCã«ãã£ãŠåŠçãããããšã¯ãããŸããã ARCã¯ã»ãšãã©ã®ã¡ã¢ãªç®¡çã¿ã¹ã¯ããããã°ã©ããè§£æŸããŸãããéçºè
ã¯ãªããžã§ã¯ããžã®å³å¯ãªåŸªç°åç
§ãåé¿ãŸãã¯æåã§ç Žæ£ããå¿
èŠããããŸãã
å®è£
ã®è©³çްã«é¢ããŠã¯ãARCãšAppleã®GCå®è£
ã®ââãã1ã€ã®éèŠãªéãã¯ãARCã¯æ¹åãããŠããªããšããããšã§ãã Appleã®GCã䜿çšããå Žåãã¢ããªã±ãŒã·ã§ã³å
šäœãGCç°å¢ã§å®è¡ããããã©ããã®ããããã§ãã ã€ãŸãã䜿çšããAppleãã¬ãŒã ã¯ãŒã¯ããµãŒãããŒãã£ã©ã€ãã©ãªãå«ããã¢ããªã±ãŒã·ã§ã³å
ã®ãã¹ãŠã®Objective-Cã³ãŒãã¯ã䜿çšããããã«GCãšäºææ§ãããå¿
èŠããããŸãã ARCãåãã¢ããªã±ãŒã·ã§ã³å
ã§æåã®ã¡ã¢ãªç®¡çãšãšãã«ãéARCãã³ãŒããšå¹³åçã«å
±åããããšã¯æ³šç®ã«å€ããŸãã ããã«ãããGCãå°å
¥ããããšãã«ééãã倧ããªäºææ§ãšä¿¡é Œæ§ã®åé¡ãªãã«ããããžã§ã¯ããéšåçã«å€æã§ããŸãã
XcodeARCã¯ãXcode 4.2ããŒã¿çãããClangïŒå¥åãApple LLVMã³ã³ãã€ã©ãïŒã䜿çšããã³ã³ãã€ã«ãéžæããå Žåã«ã®ã¿å©çšã§ããŸãã 䜿çšããã«ã¯ããObjective-C Automatic Reference Countingããšããããããããååã®èšå®ã«æ³šæããã ãã§ååã§ãã
æ¢ã«æ¢åã®ã³ãŒãããŒã¹ã§äœæ¥ããŠããå Žåããã®èšå®ã倿Žãããšãèšå€§ãªæ°ã®ãšã©ãŒãçºçããå¯èœæ§ããããŸãã ARCã¯ãããªãã®å Žæã®ã¡ã¢ãªã管çããã ãã§ãªããèªåã§ã¡ã¢ãªã管çããããšãçŠæ¢ããŠããŸãã ARCã䜿çšãããšã
retain / release / autoreleaseã¡ãã»ãŒãžããªããžã§ã¯ãã«éä¿¡
ããããšã¯ãŸã£ããåãå
¥ããããŸããã Cocoaã¯ãã®ãããªã¡ãã»ãŒãžã§ãã£ã±ãã§ãããšããäºå®ã«åºã¥ããŠãå¿
ç¶çã«å€§éã®ãšã©ãŒãçºçããŸãã
幞ããªããšã«ãXcodeã¯æ¢åã®ã³ãŒãã倿ããããŒã«ãæäŸããŸãã ãããè¡ãã«ã¯ã[
ç·šé]-> [ãªãã¡ã¯ã¿ãªã³ã°...]-> [Objective-C ARCã«å€æ...]ãéžæããŸããXcodeã䜿çšãããšãã³ãŒããæ®µéçã«å€æã§ããŸãã äœããã¹ãããæå®ããå¿
èŠãããéåžžã«ããã«ããã¯ãé€ããšããã®ããã»ã¹ã¯ã»ãšãã©èªåçã«è¡ãããŸãã
åºæ¬æ©èœCocoaã®ã¡ã¢ãªç®¡çã«ãŒã«ã¯éåžžã«ç°¡åã§ãã èŠããã«ïŒ
1.
allocãnewãcopy ã
retainããªããžã§ã¯ãã«éä¿¡
ããå Žåã
releaseãŸãã¯
autoreleaseã䜿çšããŠãããè£æ£ããå¿
èŠããããŸãã
2.æ¡é
1ã§èª¬æããæ¹æ³ãšã¯ç°ãªãæ¹æ³ã§ãªããžã§ã¯ããåãåãããªããžã§ã¯ããååã«é·ãæéãçãããç¶æ
ã«ããå¿
èŠãããå Žåã¯ã
retainãŸãã¯
copyã䜿çš
ããå¿
èŠããã
ãŸã ã åœç¶ãããã¯åŸã§è£åããå¿
èŠããããŸãã
ãããïŒã«ãŒã«ïŒã¯ãããã»ã¹ã®èªååã«å€§ããè²¢ç®ããŸãã ããªããæžãå ŽåïŒ
Foo *foo = [[Foo alloc] init]; [foo something]; return;
ã³ã³ãã€ã©ãŒã¯ãäžåè¡¡ãª
allocãæ€åºãã以äžã«å€æããŸãã
Foo *foo = [[Foo alloc] init]; [foo something]; [foo release]; return;
å®éã«ã¯ãã³ã³ãã€ã©ã¯
ãªãªãŒã¹ã¡ãã»ãŒãžããªããžã§ã¯ãã«éä¿¡ããããã®ã³ãŒããæ¿å
¥ããŸããã 代ããã«ãç¹å¥ãªã©ã³ã¿ã€ã 颿°ãžã®åŒã³åºããæ¿å
¥ããŸãã
Foo *foo = [[Foo alloc] init]; [foo something]; objc_release(foo); return;
ããã§ãããã€ãã®æé©åãé©çšã§ããŸãã -
ãªãªãŒã¹ãåå®çŸ©ãããŠããªãå Žåãã»ãšãã©ã®å Žåã
objc_releaseã¯Objective-Cã¡ãã»ãŒãžã¡ã«ããºã ããã€ãã¹ã§ããé床ããããã«åäžããŸãã
ãã®ãããªèªååã¯ãã³ãŒããããå®å
šã«ããã®ã«åœ¹ç«ã¡ãŸãã å€ãã®Cocoaéçºè
ã¯ããéåžžã«é·ãéããšããçšèªãæ¡é
2ããè§£éããŠããŸããããã¯ãã€ã³ã¹ã¿ã³ã¹å€æ°ãŸãã¯åæ§ã®å Žæã«æ ŒçŽãããŠãããªããžã§ã¯ããæå³ããŸãã éåžžãããŒã«ã«ã®äžæãªããžã§ã¯ãã«
ä¿æãš
è§£æŸãé©çš
ããŸããã
Foo *foo = [self foo]; [foo bar]; [foo baz]; [foo quux];
ãã ããæ¬¡ã®æ§æã¯éåžžã«å±éºã§ãã
Foo *foo = [self foo]; [foo bar]; [foo baz]; [self setFoo: newFoo]; [foo quux];
ããã¯ãå€ãè¿ã
ãããŸã§
retain / autoreleaseãéä¿¡ããã
-fooã®ã²ãã¿ãŒãæã€ããšã§ä¿®æ£ã§ããŸãã ããã¯æå¹ãªãªãã·ã§ã³ã§ãããã¡ã¢ãªãç©æ¥µçã«äœ¿çšããå€ãã®äžæãªããžã§ã¯ããçæã§ããŸãã ãã ããARCã¯ããã«äœåãªåŒã³åºããåå·çã«æ¿å
¥ããŸãã
Foo *foo = objc_retainAutoreleasedReturnValue([self foo]); [foo bar]; [foo baz]; [self setFoo: newFoo]; [foo quux];
ããã«ãåçŽãªã²ãã¿ãŒãäœæããå Žåã§ããARCã¯ãããå¯èœãªéãå®å
šã«ããŸãã
- (Foo *)foo { return objc_retainAutoreleaseReturnValue(_foo); }
ãã ããããã¯äžæãªããžã§ã¯ãã®éå°ãªæ°ã®åé¡ãå®å
šã«ã¯è§£æ±ºããŸããïŒ åãšåãããã«ãã²ãã¿ãŒã§ã¯
retain / autoreleaseã®çµã¿åããã䜿çšããåŒã³åºãã³ãŒãã§ã¯
retain / releaseã®çµã¿åããã䜿çšããŸãã ããã¯ééããªãç¡å¹ã§ãïŒ
ããããæž¬å®ããã«å¿é
ããªãã§ãã ããã åè¿°ã®ããã«ãARCïŒæé©åã®ããïŒã¯ãã¡ãã»ãŒãžãéä¿¡ããã ãã§ãªããç¹å¥ãªåŒã³åºãã䜿çšããŸãã
retainãš
releaseãå é
ããããšã«å ããŠããããã®åŒã³åºãã¯äžè¬çã«ããã€ãã®æäœãæé€ããŸãã
objc_retainAutoreleaseReturnValueã®å®è¡äžãã¹ã¿ãã¯ãç£èŠããåŒã³åºãå
ã®æ»ãã¢ãã¬ã¹ãèšæ¶ããŸãã ããã«ããã圌ã¯å®äºåŸã«äœãèµ·ããããæ£ç¢ºã«ç¥ãããšãã§ããŸãã ã³ã³ãã€ã«ã®æé©åããªã³ã«ããŠã
objc_retainAutoreleaseReturnValueãåŒã³åºãããšãã
æ«å°ŸåŒã³åºãã®æé©åã®çç±ã«ãªãå ŽåããããŸãã
Rantimeã¯ããã®è¿ä¿¡ã¢ãã¬ã¹ã®ã¯ã¬ã€ãžãŒãªãã§ãã¯ã䜿çšããŠãäžå¿
èŠãªäœæ¥ãåé¿ããŸãã ããã«ããã
èªåè§£æŸã®éä¿¡ãäžèŠã«ãªããä¿æã¡ãã»ãŒãžãç Žæ£ããããã«åŒã³åºãå
ã«éç¥ãããã©ã°ãèšå®ãããŸãã å
šäœã®æ§é ã¯ãã²ãã¿ãŒã§åäžã®
ãªãã€ã³ã䜿çšããåŒã³åºãã³ãŒãã§åäžã®
ãªãªãŒã¹ã䜿çšããŸããããã¯ãããå®å
šã§å¹ççãªã¢ãããŒãã§ãã
泚ïŒãã®æé©åã¯ãARCã¡ã«ããºã ã䜿çšããªãã³ãŒããšå®å
šã«äºææ§ããããŸãã
ã²ãã¿ãŒãARCã䜿çšããªãã€ãã³ãã§ã¯ãäžèšã®ãã©ã°ã¯èšå®ããããåŒã³åºãåŽã¯
ä¿æ/è§£æŸã¡ãã»ãŒãžã®å®å
šãªçµã¿åããã䜿çšã§ããŸãã
ã²ãã¿ãŒãARCã䜿çšããããåŒã³åºãå
ã¯äœ¿çšããªãã€ãã³ãã§ã¯ãã²ãã¿ãŒã¯ç¹å¥ãªã©ã³ã¿ã€ã 颿°ãããã«åŒã³åºãã³ãŒãã«æ»ããªãããšãèªèããŠããããã
ä¿æ/èªåè§£æŸã¡ãã»ãŒãžã®å®å
šãªçµã¿åããã䜿çšã§ããŸãã
äžéšã®ããã©ãŒãã³ã¹ã¯å€±ãããŸãããã³ãŒãã¯å®å
šã«æ£ãããŸãŸã§ãã
ããã«ãARCãšã³ãžã³ã¯ããã¹ãŠã®ã¯ã©ã¹ã®
-deallocã¡ãœãããèªåçã«äœæãŸãã¯å
¥åããŠããã¹ãŠã®ã€ã³ã¹ã¿ã³ã¹å€æ°ãè§£æŸããŸãã åæã«ã
-deallocãæåã§èšè¿°ããå¯èœæ§ã¯ãŸã ãããŸããïŒããã¯å€éšãªãœãŒã¹ã管çããã¯ã©ã¹ã«å¿
èŠã§ãïŒãå°æ¥çã«ã¯ã¯ã©ã¹ã€ã³ã¹ã¿ã³ã¹å€æ°ãæåã§è§£æŸããå¿
èŠã¯ãããŸããã ARCã¯æåŸã«
[super dealloc]åŒã³åºããæ¿å
¥ããã®ã§ãå¿é
ããå¿
èŠããããŸããã
èšãããããšã説æããŸãã
以åã¯ãæ¬¡ã®æ§æã䜿çšã§ããŸããã
- (void)dealloc { [ivar1 release]; [ivar2 release]; free(buffer); [super dealloc]; }
ããããããªãã¯æžãã ãã§ãïŒ
- (void)dealloc { free(buffer); }
-deallocã¡ãœãããã€ã³ã¹ã¿ã³ã¹å€æ°ãè§£æŸããã ãã®å Žåããã®æ§æïŒARCã䜿çšïŒã¯åãããšãè¡ããŸãã
ã«ãŒããšåŒ±ããªã³ã¯ARCã§ã¯ãéçºè
ã埪ç°ãªã³ã¯ãæåã§åŠçããå¿
èŠããããŸãããã®åé¡ã解決ããæåã®æ¹æ³ã¯ã匱ããªã³ã¯ã䜿çšããããšã§ãã
ARCã¯ãã«ã®åŒ±ããªã³ã¯ã䜿çšããŸãã ãã®ãããªãªã³ã¯ã¯ãåç
§å
ã®ãªããžã§ã¯ãããã©ã€ããã«ä¿ã€ã ãã§ãªããåç
§å
ã®ãªããžã§ã¯ããç Žæ£ããããšèªåçã«
nilã«ãªããŸãã 匱ããªã³ã¯ããŒãã«ããããšã§ãããããã€ã³ã¿ãŒã®åé¡ãé¢é£ããã¯ã©ãã·ã¥ãããã³ã¢ããªã±ãŒã·ã§ã³ã®äºæããªãåäœããªããªããŸãã
ãã«å¯èœãªåŒ±ããªã³ã¯ãäœæããã«ã¯ãå®£èšæã«
__weakãã¬ãã£ãã¯ã¹ã远å ããã ãã§ãã
ããšãã°ããã®ã¿ã€ãã®ã€ã³ã¹ã¿ã³ã¹å€æ°ã®äœæã¯æ¬¡ã®ãšããã§ãã
@interface Foo : NSObject { __weak Bar *_weakBar; }
ããŒã«ã«å€æ°ã¯åãæ¹æ³ã§äœæãããŸãïŒ
__weak Foo *_weakFoo = [object foo];
åŸã§éåžžã®å€æ°ãšããŠäœ¿çšã§ããŸãããå¿
èŠã«å¿ããŠå€ã¯èªåçã«
nilã«ãªããŸãã
[_weakBar doSomethingIfStillAlive];
ãã ãã
__ weak倿°ã¯ã»ãšãã©ãã¹ãŠã®æç¹ã§nilã«ãªãå¯èœæ§ãããããšã«
泚æããŠ
ãã ãã ã
ã¡ã¢ãªç®¡çã¯åºæ¬çã«ãã«ãã¹ã¬ããããã»ã¹ã§ãããççµåãªããžã§ã¯ãã¯1ã€ã®ã¹ã¬ããã§ç Žæ£ãããå¥ã®ã¹ã¬ããããã®ãªããžã§ã¯ãã«ã¢ã¯ã»ã¹ã§ããŸãã
説æããŸãã
次ã®ã³ãŒãã¯æ£ãããããŸããïŒ
if(_weakBar) [self mustNotBeNil: _weakBar];
代ããã«ãããŒã«ã«ã®åŒ·åãªãªã³ã¯ã䜿çšããŠã次ã確èªããŸãã
Bar *bar = _weakBar; if(bar) [self mustNotBeNil: bar];
ãã®å Žåã
ããŒã¯åŒ·ãåç
§ã§ããããããªããžã§ã¯ãã䜿çšãããŠããéãã£ãšãªããžã§ã¯ãïŒããã³é
nil倿°ïŒã
æå¹ã«ãªããŸãã
ARCã§ã®åŒ±ããªã³ã¯ã®ç¡å¹åã®å®è£
ã«ã¯ãObjective-Cã®åç
§ã¢ã«ãŠã³ãã£ã³ã°ã·ã¹ãã ãšåŒ±ããªã³ã¯ã®ç¡å¹åã·ã¹ãã ã®éã®ç·å¯ãªèª¿æŽãå¿
èŠã§ãã ã€ãŸãã
retainããã³
releaseããªãŒããŒã©ã€ã
ããã¯ã©ã¹ã¯ãnull蚱容匱åç
§ã®ãªããžã§ã¯ãã«ã¯ãªããŸããã ç°åžžã§ã¯ãããŸãããäžéšã®Cocoaã¯ã©ã¹ã¯ããã«èŠããã§ããŸãïŒ
NSWindowãªã© ïŒã
幞ããªããšã«ãåæ§ã®ééããç¯ããå Žåãããã°ã©ã ã¯ã次ã®ããã«ãã¯ã©ãã·ã¥ãããšãã«ã¡ãã»ãŒãžãçºè¡ããããšã«ãããããã«ãããç¥ãããŸãã
objc[2478]: cannot form weak reference to instance (0x10360f000) of class NSWindow
åæ§ã®ã¯ã©ã¹ãžã®åŒ±ãåç
§ãæ¬åœã«å¿
èŠãªå Žåã¯ã
__ weakã®ä»£ããã«
__unsafe_unretainedã䜿çšã§ããŸãã ããã«ããããªã»ãããã
ãªã匱ããªã³ã¯ãäœæãããŸãã ãã ãããã€ã³ã¿ãŒãæããŠãããªããžã§ã¯ããç Žæ£ãããåŸã¯ããã®ãã€ã³ã¿ãŒã䜿çšããŠããªãããšã確èªããå¿
èŠããããŸãïŒæåã§ãªã»ããããããšããå§ãããŸãïŒã
泚æããŠãã ããïŒnulläžå¯ã®åŒ±ããªã³ã¯ã䜿çšãããšãç«ã§éã¶ããšãã§ããŸãã
ARCã䜿çšããŠMac OS X 10.6ããã³iOS 4ã®ã¢ããªã±ãŒã·ã§ã³ãäœæããå¯èœæ§ã«ããããããããããã®OSã§ã¯ãã«å¯èœãªãŠã£ãŒã¯ãªã³ã¯ã¯äœ¿çšã§ããŸãã
ïŒç¿»èš³è
ã®ã¡ã¢ïŒARCè§£æã®ã³ã³ããã¹ãã§ãã®æç« ã®æå³ãå®å
šã«èª€è§£ããŸãããéãŒãã®åŒ±åç
§ã§ãªããã°ãªããŸããïŒããã¹ãŠã®åŒ±ããªã³ã¯ã¯
__unsafe_unretainedã§åŠçããå¿
èŠããããŸãã
ãã«å¯èœã®åŒ±ããªã³ã¯ã¯éåžžã«å±éºã§ããããããã®å¶éã«ããããããã®ã·ã¹ãã ã§ARCã䜿çšããé
åã倧å¹
ã«äœäžããŸãã
ããã¹ããããªã倧ãããªã£ãã®ã§ãããã§ç¿»èš³ã®æåã®éšåãçµäºããŸãã ç§ã¯ãããå¯èœãªéããã·ã¢èªã«ç¿»èš³ããããšããŸããããèªãŸããè³æã®99ïŒ
ãè±èªã§ããå Žåã¯ç¹ã«ç°¡åã§ã¯ãããŸããã
圌ããèšãããã«ããæ¥œãã¿ã«ã