Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Objective-C++を使ってMRCで快適に開発する

Yuki Yasoshima
September 15, 2017

 Objective-C++を使ってMRCで快適に開発する

iOSDC 2017 9/15

サンプルコード
https://github.com/objective-audio/objc_ptr_sample

Yuki Yasoshima

September 15, 2017
Tweet

More Decks by Yuki Yasoshima

Other Decks in Technology

Transcript

  1. [email protected]@TBNQMF
    0CKFDUJWF$Λ࢖ͬͯ
    .3$Ͱշదʹ։ൃ͢Δ
    :VLJ:BTPTIJNB
    [email protected]

    View Slide

  2. [email protected]@TBNQMF
    0CKFDUJWF$ͷϝϞϦ؅ཧ

    View Slide

  3. [email protected]@TBNQMF
    "VUPNBUJD3FGFSFODF$PVOUJOH
    "3$
    ࢀরΧ΢ϯλํࣜͷϝϞϦ؅ཧΛ
    ίϯύΠϥ͕ࣗಈͰߦͬͯ͘ΕΔ

    View Slide

  4. [email protected]@TBNQMF
    "3$ͷઃఆ

    View Slide

  5. [email protected]@TBNQMF
    .BOVBM3FGFSFODF$PVOUJOH
    .3$
    ࢀরΧ΢ϯλํࣜͷϝϞϦ؅ཧΛ
    खಈͰߦ͏

    View Slide

  6. [email protected]@TBNQMF
    .3$ͰͷϝϞϦ؅ཧ
    TestClass *value = [[TestClass alloc] init];
    // ࢀরΧ΢ϯτ 1
    [value release];
    // ࢀরΧ΢ϯτ 0

    View Slide

  7. [email protected]@TBNQMF
    .3$ͰͷϝϞϦ؅ཧ
    NSNumber *value = [[NSNumber alloc] initWithInt:1];
    [value retain]; // ࢀরΧ΢ϯτ 2
    [value release]; // ࢀরΧ΢ϯτ 1
    [value release]; // ࢀরΧ΢ϯτ 0

    View Slide

  8. [email protected]@TBNQMF
    .3$ͰͷϝϞϦ؅ཧ
    @autoreleasepool {
    NSNumber *value = [[NSNumber alloc] initWithInt:1];
    [value autorelease]; // ࢀরΧ΢ϯτ = 1 (- 1)
    ...
    } // ࢀরΧ΢ϯτ = 0

    View Slide

  9. [email protected]@TBNQMF
    "3$ͷ৔߹ͷΫϥε࣮૷
    @implementation Sample {
    NSNumber *_value;
    }
    - (void)setValue:(NSNumber *)value {
    _value = value;
    }
    - (NSNumber *)value {
    return _value;
    }
    @end

    View Slide

  10. [email protected]@TBNQMF
    .3$ͷ৔߹ͷΫϥε࣮૷
    @implementation Sample {
    NSNumber *_value;
    }
    - (void)setValue:(NSNumber *)value {
    [value retain];
    [_value release];
    _value = value;
    }
    - (NSNumber *)value {
    return [[_value retain] autorelease];
    }
    - (void)dealloc
    {
    [_value release];
    [super dealloc];
    }
    @end

    View Slide

  11. [email protected]@TBNQMF
    0CKFDUJWF$

    View Slide

  12. [email protected]@TBNQMF
    ֦ுࢠΛNNʹ͢Δ

    View Slide

  13. [email protected]@TBNQMF
    ࣅͨػೳͷݺͼํͷҧ͍
    0CKFDUJWF$ 4XJGU
    $
    Πϯελϯεม਺ɾϝιου ϝϯόม਺ɾؔ਺
    ΠχγϟϥΠβ ίϯετϥΫλ
    δΣωϦΫε ςϯϓϨʔτ
    ϒϩοΫɾΫϩʔδϟ ϥϜμࣜ

    View Slide

  14. [email protected]@TBNQMF
    0CKFDUJWF$
    #import
    #import
    #import
    void Sample() {
    NSString *objcText = @"Obj-C Text";
    NSLog(@"%@", objcText);
    std::string cppText = "C++ Text";
    std::cout << cppText << std::endl;
    }

    View Slide

  15. [email protected]@TBNQMF
    0CKFDUJWF$
    @implementation ObjcClass {
    std::string _text;
    }
    - (void)setText:(std::string const &)text {
    _text = text;
    }
    - (std::string const &)text {
    return _text;
    }
    @end

    View Slide

  16. [email protected]@TBNQMF
    0CKFDUJWF$
    class CppClass {
    NSString *_text;
    public:
    void setText(NSString *text) {
    _text = text;
    }
    NSString *text() {
    return _text;
    }
    };

    View Slide

  17. IUUQTHJUIVCDPNPCKFDUJWFBVEJP[email protected]@TBNQMF
    $ͷϝϞϦ؅ཧ

    View Slide

  18. [email protected]@TBNQMF
    $ΦϒδΣΫτͷΠϯελϯεԽ
    CppClass *pointer = new CppClass();
    delete pointer;

    View Slide

  19. [email protected]@TBNQMF
    $ΦϒδΣΫτͷΠϯελϯεԽ
    CppClass value_1;
    CppClass value_2(2);
    CppClass value_3{3};
    CppClass value_4 = CppClass(4);
    auto value_5 = CppClass(5);

    View Slide

  20. [email protected]@TBNQMF
    ղ์͞ΕΔλΠϛϯάʢؔ਺ʣ
    void SampleFunc() {
    CppClass value;
    } // <- value͸ؔ਺ͷείʔϓΛൈ͚Δ࣌ʹղ์͞ΕΔ

    View Slide

  21. [email protected]@TBNQMF
    ղ์͞ΕΔλΠϛϯάʢؔ਺ʣ
    void SampleFunc() {
    if (true) {
    CppClass value;
    } // <- value͸JGͷείʔϓΛൈ͚Δ࣌ʹղ์͞ΕΔ
    }

    View Slide

  22. [email protected]@TBNQMF
    ղ์͞ΕΔλΠϛϯάʢ$Ϋϥεʣ
    class CppParentClass {
    public:
    CppClass value;
    ~CppParentClass() {
    } // <- σετϥΫλ͕ݺ͹Εͨޙʹϝϯόม਺value͕ղ์͞ΕΔ
    };

    View Slide

  23. [email protected]@TBNQMF
    ղ์͞ΕΔλΠϛϯάʢ0CK$Ϋϥεʣ
    @implementation ObjcParent {
    CppClass value;
    }
    - (void)dealloc {
    [super dealloc];// <- deallocͷதͰΠϯελϯεม਺͕ղ์͞ΕΔ
    }
    @end

    View Slide

  24. [email protected]@TBNQMF
    0CKFDUJWF$ͷΦϒδΣΫτΛ
    อ࣋͢Δ$ͷΫϥεΛ࡞Δ

    View Slide

  25. [email protected]@TBNQMF
    0CKFDUJWF$ͷΦϒδΣΫτΛ
    อ࣋͢Δ$ͷΫϥεΛ࡞ͬͨ

    View Slide

  26. [email protected]@TBNQMF
    [email protected]
    //
    // objc_ptr.hpp
    //
    #pragma once
    #include
    #include
    template
    class objc_impl {
    public:
    T const value;
    objc_impl(T value) : value(value) {
    [value retain];
    }
    ~objc_impl() {
    [value release];
    }
    };
    template
    class weak_objc_ptr;
    template
    objc_ptr make_objc_ptr(T value) {
    objc_ptr ptr(value);
    [value release];
    return ptr;
    }
    template
    class weak_objc_ptr {
    std::weak_ptr> _impl;
    public:
    weak_objc_ptr() = default;
    weak_objc_ptr(objc_ptr ptr) : _impl(ptr._impl) {
    }
    objc_ptr lock() const {
    if (auto locked = _impl.lock()) {
    return objc_ptr(locked);
    } else {
    return objc_ptr();
    }
    }
    };
    template
    weak_objc_ptr to_weak(objc_ptr ptr) {
    return weak_objc_ptr(ptr);
    }
    template
    class objc_ptr {
    friend class weak_objc_ptr;
    std::shared_ptr> _impl;
    objc_ptr(std::shared_ptr> holder) : _impl(holder) {
    }
    public:
    objc_ptr() : objc_ptr(nil) {
    }
    objc_ptr(T value) : _impl(std::make_shared>(value)) {
    }
    objc_ptr(std::function handler) {
    @autoreleasepool {
    _impl = std::make_shared>(handler());
    }
    }
    T value() const {
    return _impl->value;
    }
    T operator*() const {
    return _impl->value;
    }
    explicit operator bool() const {
    return _impl->value != nil;
    }
    };

    View Slide

  27. [email protected]@TBNQMF
    [email protected]
    [email protected]@JNQM5
    [email protected]Ϋϥεͷߏ੒
    [email protected]
    ˞5͸0CKFDUJWF$ͷΫϥεͷܕʢʮ/44USJOHʯͳͲʣ
    5WBMVFʢSFUBJOͯ͠อ࣋ʣ

    View Slide

  28. View Slide

  29. [email protected]@TBNQMF
    SFUBJOͯ͠อ࣋͢Δ
    TestClass *testObj = [[[TestClass alloc] init] autorelease];
    objc_ptr test_ptr(testObj);
    NSLog(@"value : %@", test_ptr.value());
    NSLog(@"value : %@", *test_ptr);

    View Slide

  30. [email protected]@TBNQMF
    ࢀরΧ΢ϯτͦͷ··อ࣋͢Δ
    auto test_ptr = make_objc_ptr([[TestClass alloc] init]);
    NSLog(@“value : %@", *test_ptr);

    View Slide

  31. [email protected]@TBNQMF
    BVUPSFMFBTFΛ֎ͯ͠อ࣋͢Δ
    objc_ptr test_ptr(
    []() {
    return [[[TestClass alloc] init] autorelease];
    }
    );
    NSLog(@"value : %@", *test_ptr);

    View Slide

  32. [email protected]@TBNQMF
    ऑࢀরͰอ࣋͢Δ
    auto test_ptr = make_objc_ptr([[TestClass alloc] init]);
    weak_objc_ptr weak_ptr = test_ptr;
    if (auto locked_ptr = weak_ptr.lock()) {
    NSLog(@"value : %@", *locked_ptr);
    }

    View Slide

  33. [email protected]@TBNQMF
    ௚઀ऑࢀরΛฦؔ͢਺
    auto test_ptr = make_objc_ptr([[TestClass alloc] init]);
    auto weak_ptr = to_weak(test_ptr);
    auto handler = [weak_ptr]() {
    auto locked_ptr = weak_ptr.lock();
    NSLog(@"locked value : %@", locked_ptr.value());
    };
    handler();

    View Slide

  34. [email protected]@TBNQMF
    Πϯελϯεม਺Ͱ࢖͏
    @implementation Sample {
    objc_ptr _value;
    }
    - (void)setValue:(NSNumber *)value {
    _value = value;
    }
    - (NSNumber *)value {
    return *_value;
    }
    @end

    View Slide

  35. [email protected]@TBNQMF
    ͭͷ0CKFDUJWF$ΦϒδΣΫτΛ
    ෳ਺ͷ[email protected]ʹ࣋ͨͤͳ͍ํ͕ྑ͍
    ʢಛʹXFBLΛ࢖͏৔߹ʣ
    ࢖༻্ͷ஫ҙ

    View Slide

  36. [email protected]@TBNQMF
    [email protected]ಉ࢜ΛൺֱͰ͖ΔΑ͏ʹ͢ΔɺͳͲ
    "3$ͱ.3$Λ[email protected]Ͱٵऩ͢Δ
    ͞Βʹൃలͤ͞Δ

    View Slide

  37. [email protected]@TBNQMF
    ͓ΘΓ

    View Slide