Objective-c怪异的语法让很多其它平台转向iphone的开发者感到头疼不已,同时objective-c的类库虽然提供了像脚本一样容易使用的NSArray和NSDictionary容器,但是在一些对性能要求比较场合下这两个容器明显不给力,很多人选择objective-c++这种混编模式来开发,从而使用强大的C++ STL等类库。但是objc的对象内存管理相对而言比c++对象麻烦很多,比如将objc的对象直接保存在STL容器中时,默认的并不会对该对象进行任何管理,我们需要手动的retain和release。对此,可以写一个保存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的类型以在使用时方便的查看封装的对象类型。