我有一个根视图控制器A,它将segue推送到表视图控制器B.当在B中选择一行时,我想使用展开segue返回到A并将行中的文本传递回根视图A.然后我使用准备segue方法将stint发送回如下:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
ViewControllerA *vca = (ViewControllerA *)segue.destinationViewController;
vca.textString = [[_objects objectAtIndex:indexPath.row] objectForKey:@"title"];
}
Run Code Online (Sandbox Code Playgroud)
但是我不知道该怎么做,就是在didSelectRowAtIndexPath方法中调用unwind segue.
我在这里先向您的帮助表示感谢.
我在VS2015中调试我的项目,并在我的代码中抛出异常.当我尝试设置下一个语句时,我收到下面显示的错误消息.当我在VS2013中调试相同的解决方案时,我能够设置下一个语句没有任何问题.这种行为似乎发生在多种异常中.
我可以重现问题的示例代码如下所示.当在最后一行抛出异常时,TestMethod1
我可以很容易地回到VS2013中的第一个语句,但不能回到VS2015中.
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
object o = new object();
o = null;
var e = o.ToString();
}
}
Run Code Online (Sandbox Code Playgroud) c# stack-unwinding .net-4.5 visual-studio-2013 visual-studio-2015
有没有办法将NULL指针访问转换为Linux下的C++异常?类似于Java中的NullPointerException.我希望以下程序能够成功返回,而不是崩溃(假设编译器在编译期间无法找出此NULL指针访问):
class NullPointerException {};
void accessNullPointer(char* ptr) {
*ptr = 0;
}
int main() {
try {
accessNullPointer(0);
} catch (NullPointerException&) {
return 1;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我不期望任何标准的方法,因为C++下的NULL指针访问是未定义的 - 行为,只是想知道如何在x86_64 Linux/GCC下完成它.
我做了一些非常原始的研究,有可能:
sigaction()
用于注册信号处理程序).如果程序被反汇编,也可以使用导致SIGSEGV的指令.以下是GCC手册页的引用(-fnon-call-exceptions):
生成允许捕获指令以抛出异常的代码.请注意,这需要在任何地方都不存在的特定于平台的运行时支持.此外,它只允许捕获指令抛出异常,即内存引用或浮点指令.它不允许从诸如"SIGALRM"之类的任意信号处理程序抛出异常.
看来这个"特定于平台的运行时"正是我想要的.任何人都知道这样的Linux/x86_64运行时?或者如果没有这样的运行时已经存在,请给我一些关于如何实现这样的运行时的信息?
我希望该解决方案也适用于多线程程序.
在维基百科上的文件I/O的RAII的典型示例中,吞下关闭文件时发生的任何错误:
#include <iostream>
#include <string>
#include <fstream>
#include <stdexcept>
void write_to_file (const std::string & message) {
// try to open file
std::ofstream file("example.txt");
if (!file.is_open())
throw std::runtime_error("unable to open file");
// write message to file
file << message << std::endl;
// file will be closed when leaving scope (regardless of exception)
}
Run Code Online (Sandbox Code Playgroud)
似乎没有办法确定file
自动关闭时是否发生错误; 显然一个只能调用file.rdstate()
而file
上的范围.
我可以file.close()
手动调用然后检查错误,但是我必须在从示波器返回的每个地方都这样做,这违背了RAII的目的.
有些人评论说,在析构函数中只能发生文件系统损坏等不可恢复的错误,但我不相信这是正确的,因为析构函数AFAIK在关闭文件之前会刷新文件,并且在刷新时可能会发生可恢复的错误.
那么是否有一种常见的RAII方法来获取破坏期间发生的错误?我读到从析构函数中抛出异常是危险的,这听起来不像正确的方法.
我能想到的最简单的方法是注册一个回调函数,如果在破坏期间发生任何错误,析构函数将调用该函数.令人惊讶的是,似乎没有一个事件得到支持ios_base::register_callback
.这似乎是一个重大的疏忽,除非我误解了一些事情.
但也许回调是在现代课程设计中被破坏时通知错误的最常见方式?
我假设在析构函数中调用任意函数也很危险,但是将调用包装在一个try/catch
块中是完全安全的.
在try块中,调用了函数“ fun()”。在“ fun”内部创建一个类“ abc”的本地对象,并引发异常。该本地对象被捕获在“ catch”块中,并且已打印了适当的值。由于此对象是在本地创建的,因此不应打印“ 0(默认值)”,因为调用throw时将发生堆栈展开。
#include <iostream>
using namespace std;
class abc
{
int var;
public:
abc():abc(0){}
abc(int i):var(i){}
void print()
{
cout << "inside abc : " << var << endl;
}
};
void fun()
{
cout << "inside fun()" << endl;
abc obj(10);
throw obj;
}
int main()
{
try
{
cout << "inside try" << endl;
fun();
}catch(abc& ob)
{
ob.print();
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:在
abc 内部尝试
在fun()
内部:10
我的期望:
在abc 内部尝试
在fun()
内部:0
我有一个类,其 ctor 进行驱动程序调用,其 dtor 进行匹配的终止/释放驱动程序调用。这些调用可能会失败。问题自然出在 dtor 身上。
我自然知道避免 dtor 中出现异常的常识,因为如果您在堆栈展开期间抛出异常,您会得到std::terminate
. 但是 - 如果可以的话,我宁愿不只是“吞下”此类错误并且不报告它们。那么,编写这样的代码是否合法/惯用:
~MyClass() noexcept(false) {
auto result = something_which_may_fail_but_wont_throw();
if (std::uncaught_exceptions() == 0) {
throw some_exception(result);
}
}
Run Code Online (Sandbox Code Playgroud)
或者这只是巴洛克风格而不是一个好主意?
注意:此类无法访问标准输出/错误流,也无法访问日志等。
我听说有人说因为堆栈展开,异常处理有点贵.
我没有得到什么,无论我抛出异常以及是否使用"return",都会发生堆栈展开.那么区别在哪里?
例如,如果我遇到无法处理的内存问题 - 唯一的选择是停止该功能,直到我到达应该处理或通知问题的区域.那么抛出异常的另一个选择是什么?
我可以使用"return"而不是抛出异常,但那时它是一样的.我知道堆栈展开甚至可以返回六个堆栈,但所以检查返回值和"返回"组合.
欢迎解释.
如果我的析构函数被调用,那就好奇了.
(特别是对于Visual Studio,当您点击红色停止按钮时)
这不是一个关于从析构函数中抛出异常是否安全的问题.
http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.9声明:
"在堆栈展开期间,所有这些堆栈帧中的所有本地对象都被破坏.如果其中一个析构函数抛出一个异常(比如它抛出一个Bar对象),那么C++运行时系统就处于一个无法获胜的情况:它应该忽略Bar并最终进入} catch(Foo e){它最初的位置?它应该忽略Foo并寻找} catch(Bar e){handler?没有好的答案 - 任何选择都会丢失信息.
IE:如果在堆栈展开期间抛出另一个异常,那么运行时系统处于不赢状态,因为"查找"的catch处理程序是不明确的.
当堆栈展开期间抛出的异常是在try/catch块中时,是否存在上述"异常"?在这种情况下,没有歧义:
#include <iostream>
using namespace std;
class Component
{
public:
~Component()
{
cout << "In component destructor" << endl;
try
{
throw 1;
}
catch (...)
{
cout << "Caught exception in component destructor" << endl;
}
}
};
class Container
{
public:
~Container()
{
cout << "In container destructor" << endl;
Component component;
}
}
;
int main()
{
try
{
Container cont;
throw 'a';
}
catch (...) …
Run Code Online (Sandbox Code Playgroud) 我有一个64位应用程序,在Server 2003下作为服务运行.
当我连接VS Profiler或windbg时,我看到很多像下面那样的callstack.我知道在调试器(或分析器)中产生的进程使用调试堆等...但事实并非如此,因为该服务是由OS启动的,我只附加到它.
我不明白它为什么要展开堆栈.分析器显示花费了大量时间.更多信息:
•这些是使用vc9构建的发行版,在Server 2003上运行.
•系统环境变量_NO_DEBUG_HEAP设置为1.
•我正在使用Microsoft符号服务器.
为什么要捕获堆栈跟踪?它似乎正在记录它...但我无法找到它.
我的目标是验证应用程序是否真正展开堆栈,如果确实如此,请尽量避免使用它.
有任何想法吗?
ntdll!RtlVirtualUnwind
ntdll!RtlpWalkFrameChain
ntdll!RtlCaptureStackBackTrace
ntdll!RtlpCaptureStackTraceForLogging
ntdll!RtlLogStackBackTrace
ntdll!RtlDebugAllocateHeap
ntdll!RtlAllocateHeapSlowly
ntdll!RtlAllocateHeap
MSVCR90!malloc
MSVCR90!operator new
Run Code Online (Sandbox Code Playgroud) stack-unwinding ×10
c++ ×8
destructor ×3
exception ×3
.net-4.5 ×1
c# ×1
c++11 ×1
callstack ×1
gcc ×1
heap-memory ×1
idioms ×1
ios ×1
linux ×1
objective-c ×1
raii ×1
standards ×1
windows ×1