Slide 1

Slide 1 text

J04%$ dd̈̈̈̈࣫ࠇͷຐ๏0CKFDJUWF$3VOUJNF"1*̈̈̈̈dd

Slide 2

Slide 2 text

ࣗݾ঺հ *%CBOO[BJ ॴଐגࣜձࣾ"TPCJDB ৬ۀ&OHJOFFS ݺশελʔޤ৯ CBOO[BJ @CBOO[BJ@

Slide 3

Slide 3 text

ࠓ೔͸ͳ͢͜ͱ ࠇຐज़✡

Slide 4

Slide 4 text

ࠓ೔͸ͳ͢͜ͱ ࠇຐज़✡

Slide 5

Slide 5 text

ࠓ೔͸ͳ͢͜ͱ "TTPDJBUJWF3FGFSFODFT .FUIPE4XJ[[MJOH &OVNFSBUJPO.VUBUJPO)BOEMFS

Slide 6

Slide 6 text

"TTPDJBUJWF3FGFSFODFT

Slide 7

Slide 7 text

"TTPDJBUJWF3FGFSFODFT PCKD@TFU"TTPDJBUFE0CKFDU PCKD@HFU"TTPDJBUFE0CKFDU

Slide 8

Slide 8 text

࣮૷ͷ׬੒ܗ

Slide 9

Slide 9 text

࣮૷ͷ׬੒ܗ

Slide 10

Slide 10 text

PCKD@TFU"TTPDJBUFE0CKFDU WPJEPCKD@TFU"TTPDJBUFE0CKFDU JEPCKFDU DPOTUWPJELFZ JEWBMVF PCKD@"TTPDJBUJPO1PMJDZQPMJDZ Sets an associated value for a given object using a given key and association policy. ެࣜυΩϡϝϯτ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOPCKFDUJWFDPCKD@TFUBTTPDJBUFEPCKFDU MBOHVBHFPCKD

Slide 11

Slide 11 text

PCKD@TFU"TTPDJBUFE0CKFDU WPJEPCKD@TFU"TTPDJBUFE0CKFDU JEPCKFDU DPOTUWPJELFZ JEWBMVF PCKD@"TTPDJBUJPO1PMJDZQPMJDZ Sets an associated value for a given object using a given key and association policy. ެࣜυΩϡϝϯτ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOPCKFDUJWFDPCKD@TFUBTTPDJBUFEPCKFDU MBOHVBHFPCKD LFZͱQPMJDZΛ࢖༻ͯ͠౉ͨ͠ PCKFDUʹWBMVFΛؔ࿈͚ͮΔ

Slide 12

Slide 12 text

PCKD@TFU"TTPDJBUFE0CKFDU WPJEPCKD@TFU"TTPDJBUFE0CKFDU JEPCKFDU DPOTUWPJELFZ JEWBMVF PCKD@"TTPDJBUJPO1PMJDZQPMJDZ Sets an associated value for a given object using a given key and association policy. ެࣜυΩϡϝϯτ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOPCKFDUJWFDPCKD@TFUBTTPDJBUFEPCKFDU MBOHVBHFPCKD LFZͱQPMJDZΛ࢖༻ͯ͠౉ͨ͠ PCKFDUʹWBMVFΛؔ࿈͚ͮΔ

Slide 13

Slide 13 text

PCKD@HFU"TTPDJBUFE0CKFDU id objc_getAssociatedObject(id object, const void *key); Returns the value associated with a given object for a given key. ެࣜυΩϡϝϯτ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOPCKFDUJWFDPCKD@HFUBTTPDJBUFEPCKFDU MBOHVBHFPCKD

Slide 14

Slide 14 text

PCKD@HFU"TTPDJBUFE0CKFDU id objc_getAssociatedObject(id object, const void *key); Returns the value associated with a given object for a given key. ެࣜυΩϡϝϯτ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOPCKFDUJWFDPCKD@HFUBTTPDJBUFEPCKFDU MBOHVBHFPCKD PCKFDUʹؔ࿈͍ͮͨWBMVFΛLFZΛݩʹฦ͢Ͱ

Slide 15

Slide 15 text

࣮૷ͷ׬੒ܗ

Slide 16

Slide 16 text

$POW extension UICollectionView { var mainConv: Conv? { set { dataSource = newValue delegate = newValue newValue?.collectionView = self objc_setAssociatedObject( self, &UICollectionViewAssociatedObjectHandle.oldConvKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC ) } get { return objc_getAssociatedObject( self, &UICollectionViewAssociatedObjectHandle.oldConvKey ) as? Conv } } } IUUQTHJUIVCDPNCBOO[BJ$POWCMPCNBTUFS$POW$POW6*$PMMFDUJPO7JFX&YUFOTJPOTXJGU

Slide 17

Slide 17 text

.FUIPE4XJ[[MJOH

Slide 18

Slide 18 text

.FUIPE4XJ[[MJOH - طʹఆٛ͞Ε͍ͯΔϝιουͷ࣮૷ΛೖΕସ͑Δ - Swizzle Stick Ͱ͔͖ࠞͥΔ๮Β͍͠ͷͰɺ୯ޠͷΠϝʔδͱ͠ ͯ͸ͦΜͳײ͡ - https://eow.alc.co.jp/search?q=swizzle

Slide 19

Slide 19 text

.FUIPE4XJ[[MJOH - ϝιουͷऔಘ - class_getInstanceMethod - class_getClassMethod - ೖΕସ͑Δ - method_exchangeImplementations

Slide 20

Slide 20 text

ϝιουͷએݴ - (void)viewDidLoad { NSLog(@“viewDidLoad”) } - (void)_viewDidLoad { NSLog(@“_viewDidLoad”) }

Slide 21

Slide 21 text

.FUIPE4XJ[[MJOHͷॲཧ Method originalMethod = class_getInstanceMethod([self class], @selector(viewDidLoad)); Method exchangeMethod = class_getInstanceMethod([self class], @selector(_viewDidLoad)); method_exchangeImplementations(originalMethod, exchangeMethod);

Slide 22

Slide 22 text

.FUIPE4XJ[[MJOHͷॲཧ Method originalMethod = class_getInstanceMethod([self class], @selector(viewDidLoad)); Method exchangeMethod = class_getInstanceMethod([self class], @selector(_viewDidLoad)); method_exchangeImplementations(originalMethod, exchangeMethod);

Slide 23

Slide 23 text

ݺΜͰΈΔ ViewController *viewController = [ViewController new]; [viewController viewDidLoad]; ྑ͍ࢠ͸Ϛωͪ͠Όμϝͩͧ

Slide 24

Slide 24 text

ݺΜͰΈΔ ViewController *viewController = [ViewController new]; [viewController viewDidLoad]; @WJFX%JE-PBE

Slide 25

Slide 25 text

ϝιουͷએݴ - (void)viewDidLoad { NSLog(@“viewDidLoad”) } - (void)_viewDidLoad { NSLog(@“_viewDidLoad”) }

Slide 26

Slide 26 text

&YBNQMF

Slide 27

Slide 27 text

&YBNQMF

Slide 28

Slide 28 text

&YBNQMF - (void)viewDidLoad { [super viewDidLoad]; UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil] self.navigationItem.backBarButtonItem = backButtonItem; }

Slide 29

Slide 29 text

&YBNQMF + (void)load { @autoreleasepool { Method originalMethod = class_getInstanceMethod([self class], @selector(viewDidLoad)); Method exchangeMethod = class_getInstanceMethod([self class], @selector(_viewDidLoad)); method_exchangeImplementations(originalMethod, exchangeMethod); } }

Slide 30

Slide 30 text

&YBNQMF + (void)load { @autoreleasepool { Method originalMethod = class_getInstanceMethod([self class], @selector(viewDidLoad)); Method exchangeMethod = class_getInstanceMethod([self class], @selector(_viewDidLoad)); method_exchangeImplementations(originalMethod, exchangeMethod); } }

Slide 31

Slide 31 text

͖ͬ͞ͷ .FUIPE4XJ[[MJOHͷॲཧ Method originalMethod = class_getInstanceMethod([self class], @selector(viewDidLoad)); Method exchangeMethod = class_getInstanceMethod([self class], @selector(exchangedViewDidLoad)); method_exchangeImplementations(originalMethod, exchangeMethod);

Slide 32

Slide 32 text

&YBNQMF - (void)_viewDidLoad { UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil]; self.navigationItem.backBarButtonItem = backButtonItem; [self _viewDidLoad]; }

Slide 33

Slide 33 text

&YBNQMF - (void)_viewDidLoad { UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil]; self.navigationItem.backBarButtonItem = backButtonItem; [self _viewDidLoad]; }

Slide 34

Slide 34 text

&YBNQMF - (void)_viewDidLoad { UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil]; self.navigationItem.backBarButtonItem = backButtonItem; [self _viewDidLoad]; }

Slide 35

Slide 35 text

˞஫ҙ఺ - (void)viewDidLoad { [super viewDidLoad]; … }

Slide 36

Slide 36 text

4FHVF"EEJUJPO public extension UIViewController { fileprivate func swizzling() { let prepareForSegue = class_getInstanceMethod(type(of: self), #selector(UIViewController.prepare)) let _prepare = class_getInstanceMethod(type(of: self), #selector(UIViewController._prepare(segue:sender:))) method_exchangeImplementations(prepareForSegue!, _prepare!) } public func performSegue(_ withIdentifier: String, closure: ((UIStoryboardSegue) -> Void)? = nil) { swizzling() self.performSegue(withIdentifier: withIdentifier, sender: SegueEventHolder(segueClosure: closure)) swizzling() } } IUUQTHJUIVCDPNCBOO[BJ4FHVF"EEJUJPOCMPCNBTUFS$MBTTFT4FHVF"EEJUJPOTXJGU

Slide 37

Slide 37 text

&OVNFSBUJPO.VUBUJPO)BOEMFS

Slide 38

Slide 38 text

&OVNFSBUJPO.VUBUJPO)BOEMFS - objc_enumerationMutation - objc_setEnumerationMutationHandler

Slide 39

Slide 39 text

[email protected] [email protected] JEPCK Inserted by the compiler when a mutation is detected during a foreach iteration. ެࣜυΩϡϝϯτ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOPCKFDUJWFDPCKD@FOVNFSBUJPONVUBUJPO MBOHVBHFPCKD

Slide 40

Slide 40 text

[email protected] [email protected] JEPCK Inserted by the compiler when a mutation is detected during a foreach iteration. ެࣜυΩϡϝϯτ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOPCKFDUJWFDPCKD@FOVNFSBUJPONVUBUJPO MBOHVBHFPCKD ҙ༁GPSFBDIͰJUFSBUJPO͍ͯ͠Δ్தͰ ഑ྻʹมߋΛՃ͑Δͱ͜ͷؔ਺ΛׂΓࠐΜͰݺͿΑ

Slide 41

Slide 41 text

[email protected] Discussion The compiler inserts this function when it detects that an object is mutated during a foreach iteration. The function is called when a mutation occurs, and the enumeration mutation handler is enacted if it is set up (via the objc_setEnumerationMutationHandler function). If the handler is not set up, a fatal error occurs.

Slide 42

Slide 42 text

[email protected] Discussion The compiler inserts this function when it detects that an object is mutated during a foreach iteration. The function is called when a mutation occurs, and the enumeration mutation handler is enacted if it is set up (via the objc_setEnumerationMutationHandler function). If the handler is not set up, a fatal error occurs. PCKD@TFU&OVNFSBUJPO.VUBUJPO)BOEMFS ͰTFUVQ͞Εͨؔ਺͕ηοτ͞Ε͍ͯͳ͔ͬͨΒ GBUBMFSSPSΛىͥ͜͢

Slide 43

Slide 43 text

'BUBM&SSPSͷݕূ NSMutableArray *array = @[@1, @2, @3].mutableCopy; for (NSNumber *number in array) { [array removeObject:number]; }

Slide 44

Slide 44 text

'BUBM&SSPSͷݕূ NSMutableArray *array = @[@1, @2, @3].mutableCopy; for (NSNumber *number in array) { [array removeObject:number]; }

Slide 45

Slide 45 text

'BUBM&SSPSͷݕূ 2018-08-31 00:20:49.538515+0900 iOSDC-BlackMagick[65259:1688283] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x6000000523f0> was mutated while being enumerated.' *** First throw call stack: ( 0 CoreFoundation 0x000000011085c1e6 __exceptionPreprocess + 294 1 libobjc.A.dylib 0x000000010fef1031 objc_exception_throw + 48 2 CoreFoundation 0x00000001108d004c __NSFastEnumerationMutationHandler + 124 3 iOSDC-BlackMagick 0x000000010f5ea20c -[ViewController enumerationMutation] + 556 4 iOSDC-BlackMagick 0x000000010f5e9a69 -[ViewController viewDidLoad] + 393 5 UIKit 0x0000000110e7d131 -[UIViewController loadViewIfRequired] + 1215 6 UIKit 0x0000000110ec420c -[UINavigationController _updateScrollViewFromViewController:toViewController:] + 6 7 UIKit 0x0000000110ec44ea -[UINavigationController _startTransition:fromViewController:toViewController:] + 136 8 UIKit 0x0000000110ec561e -[UINavigationController _startDeferredTransitionIfNeeded:] + 870 9 UIKit 0x0000000110ec686c -[UINavigationController __viewWillLayoutSubviews] + 150 10 UIKit 0x000000011111ed0b -[UILayoutContainerView layoutSubviews] + 231 11 UIKit 0x000000012d7e361c -[UILayoutContainerViewAccessibility layoutSubviews] + 42 12 UIKit 0x0000000110da87a8 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1515 13 QuartzCore 0x0000000116847456 -[CALayer layoutSublayers] + 177 14 QuartzCore 0x000000011684b667 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 395 15 QuartzCore 0x00000001167d20fb _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 343 16 QuartzCore 0x00000001167ff79c _ZN2CA11Transaction6commitEv + 568 17 UIKit 0x0000000110cf3269 __34-[UIApplication _firstCommitBlock]_block_invoke_2 + 141 18 CoreFoundation 0x00000001107feb0c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12 19 CoreFoundation 0x00000001107e32db __CFRunLoopDoBlocks + 331 20 CoreFoundation 0x00000001107e2a84 __CFRunLoopRun + 1284 21 CoreFoundation 0x00000001107e230b CFRunLoopRunSpecific + 635 22 GraphicsServices 0x00000001159d0a73 GSEventRunModal + 62 23 UIKit 0x0000000110cd9057 UIApplicationMain + 159 24 iOSDC-BlackMagick 0x000000010f5eab0f main + 111 25 libdyld.dylib 0x00000001142b9955 start + 1 26 ??? 0x0000000000000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException

Slide 46

Slide 46 text

'BUBM&SSPSͷݕূ 2018-08-31 00:20:49.538515+0900 iOSDC-BlackMagick[65259:1688283] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x6000000523f0> was mutated while being enumerated.' *** First throw call stack: ( 0 CoreFoundation 0x000000011085c1e6 __exceptionPreprocess + 294 1 libobjc.A.dylib 0x000000010fef1031 objc_exception_throw + 48 2 CoreFoundation 0x00000001108d004c __NSFastEnumerationMutationHandler + 124 3 iOSDC-BlackMagick 0x000000010f5ea20c -[ViewController enumerationMutation] + 556 4 iOSDC-BlackMagick 0x000000010f5e9a69 -[ViewController viewDidLoad] + 393 5 UIKit 0x0000000110e7d131 -[UIViewController loadViewIfRequired] + 1215 6 UIKit 0x0000000110ec420c -[UINavigationController _updateScrollViewFromViewController:toViewController:] + 6 7 UIKit 0x0000000110ec44ea -[UINavigationController _startTransition:fromViewController:toViewController:] + 136 8 UIKit 0x0000000110ec561e -[UINavigationController _startDeferredTransitionIfNeeded:] + 870 9 UIKit 0x0000000110ec686c -[UINavigationController __viewWillLayoutSubviews] + 150 10 UIKit 0x000000011111ed0b -[UILayoutContainerView layoutSubviews] + 231 11 UIKit 0x000000012d7e361c -[UILayoutContainerViewAccessibility layoutSubviews] + 42 12 UIKit 0x0000000110da87a8 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1515 13 QuartzCore 0x0000000116847456 -[CALayer layoutSublayers] + 177 14 QuartzCore 0x000000011684b667 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 395 15 QuartzCore 0x00000001167d20fb _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 343 16 QuartzCore 0x00000001167ff79c _ZN2CA11Transaction6commitEv + 568 17 UIKit 0x0000000110cf3269 __34-[UIApplication _firstCommitBlock]_block_invoke_2 + 141 18 CoreFoundation 0x00000001107feb0c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12 19 CoreFoundation 0x00000001107e32db __CFRunLoopDoBlocks + 331 20 CoreFoundation 0x00000001107e2a84 __CFRunLoopRun + 1284 21 CoreFoundation 0x00000001107e230b CFRunLoopRunSpecific + 635 22 GraphicsServices 0x00000001159d0a73 GSEventRunModal + 62 23 UIKit 0x0000000110cd9057 UIApplicationMain + 159 24 iOSDC-BlackMagick 0x000000010f5eab0f main + 111 25 libdyld.dylib 0x00000001142b9955 start + 1 26 ??? 0x0000000000000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException 5FSNJOBUJOHBQQEVFUPVODBVHIUFYDFQUJPO/4(FOFSJD&YDFQUJPO SFBTPO $PMMFDUJPO@@/4"SSBZ.YGXBTNVUBUFEXIJMF CFJOHFOVNFSBUFE

Slide 47

Slide 47 text

[email protected] Discussion The compiler inserts this function when it detects that an object is mutated during a foreach iteration. The function is called when a mutation occurs, and the enumeration mutation handler is enacted if it is set up (via the objc_setEnumerationMutationHandler function). If the handler is not set up, a fatal error occurs.

Slide 48

Slide 48 text

PCKD@TFU&OVNFSBUJPO.VUBUJPO)BOEMFS WPJEPCKD@TFU&OVNFSBUJPO.VUBUJPO)BOEMFS WPJE IBOEMFS JE Sets the current mutation handler. ެࣜυΩϡϝϯτ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOPCKFDUJWFDPCKD@TFUFOVNFSBUJPONVUBUJPOIBOEM MBOHVBHFPCKD

Slide 49

Slide 49 text

PCKD@TFU&OVNFSBUJPO.VUBUJPO)BOEMFS WPJEPCKD@TFU&OVNFSBUJPO.VUBUJPO)BOEMFS WPJE IBOEMFS JE Sets the current mutation handler. ެࣜυΩϡϝϯτ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOPCKFDUJWFDPCKD@TFUFOVNFSBUJPONVUBUJPOIBOEM MBOHVBHFPCKD ҙ༁มߋ͞Εͨ࣌ͷॲཧΛTFU͢Δͥ

Slide 50

Slide 50 text

࢖ͬͯΈͨ void function(NSMutableArray *array) { NSLog(@"array: %@", array); } - (void)enumerationMutation { objc_setEnumerationMutationHandler(function); NSMutableArray *array = @[@1, @2, @3].mutableCopy; for (NSNumber *number in array) { [array removeObject:number]; } }

Slide 51

Slide 51 text

࢖ͬͯΈͨ void function(NSMutableArray *array) { NSLog(@"array: %@", array); } - (void)enumerationMutation { objc_setEnumerationMutationHandler(function); NSMutableArray *array = @[@1, @2].mutableCopy; for (NSNumber *number in array) { [array removeObject:number]; } }

Slide 52

Slide 52 text

࢖ͬͯΈͨ void function(NSMutableArray *array) { NSLog(@"array: %@", array); } - (void)enumerationMutation { objc_setEnumerationMutationHandler(function); NSMutableArray *array = @[@1, @2].mutableCopy; for (NSNumber *number in array) { [array removeObject:number]; } }

Slide 53

Slide 53 text

ϩά array: ( 2, 3 ) array: ( 3 )

Slide 54

Slide 54 text

࢖ͬͯΈͨ void function(NSMutableArray *array) { NSLog(@“͓ئ͍ࢮͳͳ͍Ͱʂ”); } - (void)enumerationMutation { objc_setEnumerationMutationHandler(function); NSMutableArray *array = @[@1, @2].mutableCopy; for (NSNumber *number in array) { [array removeObject:number]; } objc_setEnumerationMutationHandler(nil); }

Slide 55

Slide 55 text

࢖ͬͯΈͨ void function(NSMutableArray *array) { NSLog(@“͓ئ͍ࢮͳͳ͍Ͱʂ”); } - (void)enumerationMutation { objc_setEnumerationMutationHandler(function); NSMutableArray *array = @[@1, @2].mutableCopy; for (NSNumber *number in array) { [array removeObject:number]; } objc_setEnumerationMutationHandler(nil); } ௒ศར

Slide 56

Slide 56 text

࢖ͬͯΈͨ void function(NSMutableArray *array) { NSLog(@“͓ئ͍ࢮͳͳ͍Ͱʂ”); } - (void)enumerationMutation { objc_setEnumerationMutationHandler(function); NSMutableArray *array = @[@1, @2].mutableCopy; for (NSNumber *number in array) { [array removeObject:number]; } objc_setEnumerationMutationHandler(nil); } ӕͰ͢

Slide 57

Slide 57 text

࢖ͬͯΈͨ void function(NSMutableArray *array) { NSLog(@“͓ئ͍ࢮͳͳ͍Ͱʂ”); } - (void)enumerationMutation { objc_setEnumerationMutationHandler(function); NSMutableArray *array = @[@1, @2].mutableCopy; for (NSNumber *number in array) { [array removeObject:number]; } objc_setEnumerationMutationHandler(nil); } ࢧ཭໓྾ͳࢥߟɾൃݴ

Slide 58

Slide 58 text

࠷ޙʹ You typically don't need to use the Objective-C runtime library directly when programming in Objective-C. This API is useful primarily for developing bridge layers between Objective-C and other languages, or for low-level debugging.

Slide 59

Slide 59 text

࠷ޙʹ You typically don't need to use the Objective-C runtime library directly when programming in Objective-C. This API is useful primarily for developing bridge layers between Objective-C and other languages, or for low-level debugging. ීஈͷ։ൃͰ͋Ε͹3VOUJNF"1*࢖͏ඞཁ͕ͳ͍ ଞͷݴޠͷϒϦοδϯά΍௿ϨΠϠʔͷσόοάʹ͸ͱͯ΋ ໾ཱͭΑ

Slide 60

Slide 60 text

࠷ޙʹ You typically don't need to use the Objective-C runtime library directly when programming in Objective-C. This API is useful primarily for developing bridge layers between Objective-C and other languages, or for low-level debugging. ීஈͷ։ൃͰ͋Ε͹3VOUJNF"1*࢖͏ඞཁ͕ͳ͍ ଞͷݴޠͷϒϦοδϯά΍௿ϨΠϠʔͷσόοάʹ͸ͱͯ΋ ໾ཱͭΑ

Slide 61

Slide 61 text

·ͱΊ - ϓϩύςΟΛੜ΍ͤΔ - ϝιουΛೖΕସ͑ΒΕΔ - ͓ئ͍ࢮͳͳ͍Ͱʂ͕දݱͰ͖Δ - ελʔ͍ͩ͘͞

Slide 62

Slide 62 text

͓͠·͍a ?P?