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

06641ec93c5914e0db74cddff2ec6004?s=47 Yuki Yasoshima
September 15, 2017

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

iOSDC 2017 9/15

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

06641ec93c5914e0db74cddff2ec6004?s=128

Yuki Yasoshima

September 15, 2017
Tweet

Transcript

  1. 7.

    IUUQTHJUIVCDPNPCKFDUJWFBVEJPPCKD@QUS@TBNQMF .3$ͰͷϝϞϦ؅ཧ NSNumber *value = [[NSNumber alloc] initWithInt:1]; [value retain];

    // ࢀরΧ΢ϯτ 2 [value release]; // ࢀরΧ΢ϯτ 1 [value release]; // ࢀরΧ΢ϯτ 0
  2. 10.

    IUUQTHJUIVCDPNPCKFDUJWFBVEJPPCKD@QUS@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
  3. 14.

    IUUQTHJUIVCDPNPCKFDUJWFBVEJPPCKD@QUS@TBNQMF 0CKFDUJWF$ #import <Foundation/Foundation.h> #import <string> #import <iostream> void Sample()

    { NSString *objcText = @"Obj-C Text"; NSLog(@"%@", objcText); std::string cppText = "C++ Text"; std::cout << cppText << std::endl; }
  4. 26.

    IUUQTHJUIVCDPNPCKFDUJWFBVEJPPCKD@QUS@TBNQMF PCKD@QUSIQQ // // objc_ptr.hpp // #pragma once #include <memory>

    #include <functional> template <typename T> class objc_impl { public: T const value; objc_impl(T value) : value(value) { [value retain]; } ~objc_impl() { [value release]; } }; template <typename T> class weak_objc_ptr; template <typename T> objc_ptr<T> make_objc_ptr(T value) { objc_ptr<T> ptr(value); [value release]; return ptr; } template <typename T> class weak_objc_ptr { std::weak_ptr<objc_impl<T>> _impl; public: weak_objc_ptr() = default; weak_objc_ptr(objc_ptr<T> ptr) : _impl(ptr._impl) { } objc_ptr<T> lock() const { if (auto locked = _impl.lock()) { return objc_ptr<T>(locked); } else { return objc_ptr<T>(); } } }; template <typename T> weak_objc_ptr<T> to_weak(objc_ptr<T> ptr) { return weak_objc_ptr<T>(ptr); } template <typename T> class objc_ptr { friend class weak_objc_ptr<T>; std::shared_ptr<objc_impl<T>> _impl; objc_ptr(std::shared_ptr<objc_impl<T>> holder) : _impl(holder) { } public: objc_ptr() : objc_ptr(nil) { } objc_ptr(T value) : _impl(std::make_shared<objc_impl<T>>(value)) { } objc_ptr(std::function<T(void)> handler) { @autoreleasepool { _impl = std::make_shared<objc_impl<T>>(handler()); } } T value() const { return _impl->value; } T operator*() const { return _impl->value; } explicit operator bool() const { return _impl->value != nil; } };
  5. 29.
  6. 32.
  7. 33.

    IUUQTHJUIVCDPNPCKFDUJWFBVEJPPCKD@QUS@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();
  8. 34.

    IUUQTHJUIVCDPNPCKFDUJWFBVEJPPCKD@QUS@TBNQMF Πϯελϯεม਺Ͱ࢖͏ @implementation Sample { objc_ptr<NSNumber *> _value; } -

    (void)setValue:(NSNumber *)value { _value = value; } - (NSNumber *)value { return *_value; } @end