Objective c Obj-C范围/等同于C#IDisposable和#x27;使用';,或C++;自动变量?

Objective c Obj-C范围/等同于C#IDisposable和#x27;使用';,或C++;自动变量?,objective-c,automatic-ref-counting,Objective C,Automatic Ref Counting,我想创建绑定到作用域的obj c对象,以便对象知道何时进入/退出作用域 这是一个ARC环境 目标是创建一些日志实用程序,这些实用程序可以轻松生成封装流程的日志,如下所示: onHttpRequest { deduce encoding - found UTF-8! parsing xml took 0.08 seconds unknown request found... sending error. sendingResponse took 0.02 secon

我想创建绑定到作用域的obj c对象,以便对象知道何时进入/退出作用域

这是一个ARC环境

目标是创建一些日志实用程序,这些实用程序可以轻松生成封装流程的日志,如下所示:

onHttpRequest {
    deduce encoding - found UTF-8!
    parsing xml took 0.08 seconds
    unknown request found... sending error.
    sendingResponse took 0.02 seconds.
} (0.10 seconds)
NSLog(@"Logging at indent level 0");
{
    ScopedLogMessage* log1 = [[ScopedLogMessage alloc] initWithMessage:@"Begin nested operations"];
    [log1 debugLog:@"Logging at indent level 1"];
    {
        ScopedLogMessage* log2 = [[ScopedLogMessage alloc] initWithMessage:@"Another level of nested operations" parentLog:log1];
        [log2 debugLog:@"Logging at indent level 2"];
    }
    [log1 debugLog:@"Logging at indent level 1 again"];
}
NSLog(@"Logging at indent level 0 again");
<>这在过去的C++和C语言中是很容易的。现在我正在学习obj-c,想不出一个干净的方法来实现这一点

在C++中,使用<代码> Auto 变量是很容易的:

struct ScopedLogMessage
{
    ScopedLogMessage(std::string msg) { debugPrint(indentStr + msg + newline); indent ++; }
    ~ScopedLogMessage() { indent --; debugPrint(indentStr + "}" + newline); }
}

void onHttpRequest()
{
    ScopedLogMessage x("onHttpRequest");
    debugPrint("deduce encoding ...");
    debugPrint("more stuff ....");
}
或者在C#中,使用
IDisposable
using(){}
块:

class ScopedLogMessage : IDisposable
{
    public ScopedLogMessage(string msg) { debugPrint(indentStr + msg + newline); indent ++; }
    public void Dispose() { indent --; debugPrint(indentStr + "}" + newline); }
}

static void onHttpRequest()
{
    using(ScopedLogMessage x = new ScopedLogMessage("onHttpRequest"))
    {
        debugPrint("deduce encoding ...");
        debugPrint("more stuff ....");
    }
}

在objective-C中是否可以执行类似的操作?

当ARC变量超出范围时,编译器会自动保留和释放它们,因此代码如下所示:

onHttpRequest {
    deduce encoding - found UTF-8!
    parsing xml took 0.08 seconds
    unknown request found... sending error.
    sendingResponse took 0.02 seconds.
} (0.10 seconds)
NSLog(@"Logging at indent level 0");
{
    ScopedLogMessage* log1 = [[ScopedLogMessage alloc] initWithMessage:@"Begin nested operations"];
    [log1 debugLog:@"Logging at indent level 1"];
    {
        ScopedLogMessage* log2 = [[ScopedLogMessage alloc] initWithMessage:@"Another level of nested operations" parentLog:log1];
        [log2 debugLog:@"Logging at indent level 2"];
    }
    [log1 debugLog:@"Logging at indent level 1 again"];
}
NSLog(@"Logging at indent level 0 again");
输出将是:

Logging at indent level 0
Begin nested operations {
    Logging at indent level 1
    Another level of nested operations {
        Logging at indent level 2
    }
    Logging at indent level 1 again
}
Logging at indent level 0 again
ScopedLogMessage类的代码:

ScopedLogMessage.h:

如您所见,
dealoc
方法是关键,相当于C#
Dispose
。如果没有ARC,您将被迫释放日志并在
dealloc
方法上调用
[super dealloc]


希望有帮助。

是的;编辑说明了不使用ObjultC++的任何理由,所以你可以继续使用C++技术吗?我个人的原因是我对Obj-C++一无所知,而且整个环境对我来说是全新的。当然,如果XCode让我选择创建一个“目标C++类”,我会更认真对待它。我只是看不到任何关于Obj-C++的东西。。。它在一个典型的OSX/XCODEL环境中是否通用?就像Objtovi-C在C语言上简单地添加语言特性一样,Objul-C++在C++的顶部添加相同的特性。默认情况下,扩展名为
.mm
的任何文件都编译为Objective-C++。您还可以指示Xcode将任何特定文件编译为Objective-C++,覆盖它根据文件扩展名选择的文件。这非常有帮助,但我会收到一条编译器警告,提示
logMessage
未使用。是否有方法仅对
ScopedLogMessage
对象抑制此警告?我认为允许ARC在上次使用对象后释放该对象,这可能是在对象超出范围之前。测试应该在大括号内有另一个日志(在
//做点有趣的事!
)以确保“Exiting…”消息出现在后面。嗨@KenThomases我对答案也不满意,所以我创建了一个完整的解决方案,避免了静态“indent”变量(对于多线程来说非常糟糕)并在类内执行日志以避免在时间之前被处理。非常有趣!事实上,我想我可能会使用线程本地堆栈来跟踪“父线程”,而不必将它们传入,这在容易出错的情况下很烦人