Objective-c与c++混编中的objc对象内存管理

    技术2022-05-18  14

    Objective-c怪异的语法让很多其它平台转向iphone的开发者感到头疼不已,同时objective-c的类库虽然提供了像脚本一样容易使用的NSArrayNSDictionary容器,但是在一些对性能要求比较场合下这两个容器明显不给力,很多人选择objective-c++这种混编模式来开发,从而使用强大的C++ STL等类库。但是objc的对象内存管理相对而言比c++对象麻烦很多,比如将objc的对象直接保存在STL容器中时,默认的并不会对该对象进行任何管理,我们需要手动的retainrelease。对此,可以写一个保存objective-c对象的c++句柄类,利用c++的一些特性来省去这些内存操作,从而避免错误的产生。

    个人写的ns_handle类参考代码如下。

    ns_handle.h

    /*

     *  ns_handle.h

     *  ns_handle

     *

     *  Created by leondun on 11-3-23.

     *  Copyright 2011 leondun. All rights reserved.

     *

     */

     

    //===================================

     

    class ns_handle

    {

    private:

          typedef enum

          {

                _retain,

                _assign,

                _copy,

          }_mem_type;

         

    public:

          static const _mem_type retain = _retain;

          static const _mem_type assign = _assign;

          static const _mem_type copy = _copy;

         

    public:

          ns_handle(id nsObj,_mem_type mem_type = retain);

          ns_handle(const ns_handle & handle);

          ns_handle & operator=(const ns_handle & handle);

          id & operator*();

          ~ns_handle();

         

    private:

          id m_nsObj;

    };

     

    //===================================

     

    inline ns_handle::ns_handle(id nsObj,_mem_type mem_type)

    :m_nsObj(nsObj)

    {

          switch (mem_type)

          {

                case retain:

                      [m_nsObj retain];

                      break;

                case assign:

                      break;

                case copy:

                      [m_nsObj copy];

                      break;            

                default:

                      break;

          }   

    }

     

    inline ns_handle::ns_handle(const ns_handle & handle)

    :m_nsObj(handle.m_nsObj)

    {

          [m_nsObj retain];

    }

     

    inline ns_handle & ns_handle::operator=(const ns_handle & handle)

    {

          [m_nsObj release];

          m_nsObj = handle.m_nsObj;

          [m_nsObj retain];

          return *this;

    }

     

    inline id & ns_handle::operator*()

    {

          return m_nsObj;

    }

     

    inline ns_handle::~ns_handle()

    {

          [m_nsObj release];

    }

    对于任意的objective-c对象,使用handle包装该对象即可,然后我们就可以轻松的把这个handle对象丢在各种容器中使用而不用再考虑objective-c对象的内存管理。

    handle的构造函数中的第2个参数是objc对象的内存管理方式,分别为retian,copy,assign。默认的是handle::retain的方式。这三种方式类似objc里的@property方法的使用。

    对于retain方式,即构建handle的时候原objc对象引用加一,析构的时候引用减一。

    对于copy方式,首先该objc对象必须继承NSCopying协议并实现CopyWithZone的方法,才可以正常使用。

    对于assign方式,则默认仅做赋值处理。

    通过重载(*)解运算符,在调用handle的时候可以直接用*handle来获取句柄中保存的objc对象。

    举例使用:我们构建一个NSString对象的过程并使用的过程如下:

        NSString * s = @"Test";

        ns_handle handle(s,ns_handle::copy);

        std::vector<ns_handle> vec;

        vec.push_back(handle);

    NSLog(@"%@",*handle);      

         这个类的一个缺点是仅定义ns_handle类无法直观的看到该类中包含的objc对象的类型,对于这点可以用模板类加上objc的类型以在使用时方便的查看封装的对象类型。


    最新回复(0)