测试已测试 | ✗ |
语言语言 | Objective C++Objective C++ |
许可 | BSD |
发布最后发布 | 2014年12月 |
由 Alexander Dodatko 维护。
这是一个 ObjectiveC++ 类,使用块来释放资源。范围守护会在其 C++ 析构函数中执行块,并确保即使在抛出异常的情况下也能正确管理资源。
这个类将 RAII 习语引入了 iOS 开发者的世界。
License : BSD
正确手动管理资源是一项艰苦的工作,也是错误的主要来源。
using namespace ::std;
void bad(const char* p)
{
FILE* fh = fopen(p,"r"); // acquire
// use f
if ( someCondition )
{
// Oops! Looks like we are missing the fclose() statement and leaking the resource
return;
}
f(); // OOPS! Exceptions can be thrown.
fclose(fh); // release
cout << "fclose() called" << endl;
}
范围守护习语可以被看作是一个低级资源的 autorelease 或 @autoreleasepool 语句。与 autorelease 不同,资源在 函数退出时 被释放。此外,它同时也适用于 返回 和 @throw 异常 的情况。
The ObjcScopedGuard class uses Objective-C blocks for easiy integration with existing legacy code.
应该使用这个类来处理没有由 ARC 管理的资源,包括
可以将上一节的代码以资源安全可扩展的方式重写
using namespace ::std;
using namespace ::Utils;
void good(const char* p)
{
FILE* fh = fopen(p,"r"); // acquire
// the block to perform cleanup actions
GuardCallbackBlock releaseBlock_ = ^void( void )
{
cout << "fclose() called" << endl;
::fclose( fh ); // release
};
// creating a guard
ObjcScopedGuard guard( releaseBlock_ );
// use f
if ( someCondition )
{
// Now the scoped guard will release the resource
return;
}
f(); // OOPS! Exceptions can be thrown.
// Fclose should not be called explicitly since the
/*
fclose(fh); // release
cout << "fclose() called" << endl;
*/
}
有时候对象应该比函数范围的生命周期更长,并集成到 Cocoa autoreleasepool 系统 中。这意味着,应该能够对守护进行 保留 和 释放。本库中的 ObjcReferenceCountGuard
类解决了上述问题。
using namespace ::std;
using namespace ::Utils;
void good_retain_release(const char* p, id<GuardHolderProtocol> guardHolder)
{
FILE* fh = fopen(p,"r"); // acquire
// the block to perform cleanup actions
GuardCallbackBlock releaseBlock_ = ^void( void )
{
cout << "fclose() called" << endl;
::fclose( fh ); // release
};
// creating a guard and storing a strong reference to it
guardHolder.guard = [ [ ObjcReferendeCountGuard alloc ] initWithBlock: releaseBlock_ ];
// use f
if ( someCondition )
{
// Now the scoped guard will release the resource
return;
}
f(); // OOPS! Exceptions can be thrown.
// Fclose should not be called explicitly since the
/*
fclose(fh); // release
cout << "fclose() called" << endl;
*/
}
一些 代码示例 来自 Andrey Dankevich 的 "Resource Acquisition is Initialization" 演示文稿。