我完全清楚Swift没有try/catch机制来捕获异常(好的,Swift 2.0现在支持它们).我也理解许多API方法会返回一个NSError,如果出现问题,它将填充错误对象.所以请不要指出这个问题:Swift语言中的错误处理
但是这仍然没有解释如何对自己的代码中的运行时错误作出反应,例如数组越界访问或强制解包一个nil的可选值.例如:
var test: String?
test = nil
println(test!) //oops!
Run Code Online (Sandbox Code Playgroud)
要么
var arr = [0,1,2]
for i = 0...3 {
println(arr[i]) //oops!
}
Run Code Online (Sandbox Code Playgroud)
每个程序员偶尔会犯这样的错误,应该有一种方法至少记录它们以供以后分析.在调试时,Xcode可以向我们展示这些,但如果最终用户或beta测试人员遇到这种情况怎么办?在纯C中有信号处理,它也可以在Objective-C中使用.在Swift中有这样的东西吗?在应用程序死亡之前输入的集中回调?
更新:
让我重新解释一个问题:在一个大项目中,在每个循环和强制解包时手动检查上述错误是不可行的.当运行时错误最终确实发生时,是否会有一个回调,比如Objective C的segfault处理或NSSetUncaughtExceptionHandler,它会被调用,以便错误可以与崩溃的堆栈跟踪一起记录/通过电子邮件发送?
我们的应用程序需要通过Google Analytics的Measurement Protocol收集使用数据.
我们可以成功将"appview"匹配发送到Google Analytics服务器,并通过它获得正确的响应(GIF图像).appview点击显示在GA仪表板上,以及原始国家/地区,会话持续时间等.
我们还有几个自定义维度和指标,我们希望跟踪每个匹配.我们已在GA管理面板中设置了正确的范围,索引和活动状态.我们有3个命中范围的维度,3个用户级别的维度和1个命中范围的度量,都设置为活动状态.
我们按照文档中的说明发送维度和指标
https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#customs
附在他们申请的命中,如下:
...&cm1*= 3 < - 表示指标
和
...&cd6*= 15 < - 维度(某些维度具有数值,其他维度为文本)
问题是这些指标和维度没有显示在我们的自定义报告中:报告总是说"此视图没有数据".例如,我们有一个报告,其中包含一个维度和一个指标,没有任何过滤器,设置为"任何视图".如果报告的类型是资源管理器,平面表或地图叠加,则它从不显示任何内容.
自收到命中并出现在仪表板中已有好几天,但报告仍然是空的.因此,请忽略任何处理延迟.
我们尝试发送"事件"点击而不是"appview"点击 - 再次,点击显示在仪表板中,但报告是空的.
如果不使用维度和指标,我们就无法获得任何有用的见解 - 所以没有这个就没有办法实现.
由于描述的原因太长,我们无法使用任何Google提供的Google Analytics库.
我们还需要做些什么来查看这些报告中的数据吗?
我一直觉得C++编程不方便的一件事是缺少一个好的map/dictionary/hash table/associative array容器类.C#,Java和Objective-C都有这样的类,即Dictionary <>,Hashtable和NSDictionary,它们大多数都是开箱即用的,具有所有数据类型.但是STL的stl :: map和Boost的boost :: unordered_map都非常笨拙且过于冗长,即使对于平凡的日常任务也是如此.我想知道在一些开源库中是否存在C++等价物,它更类似于上述平台的语法和功能.在这三个中,C#的Dictionary <>是我最喜欢的,因为它是强类型的,语法非常短,而且非常通用.所以这样的事情会很完美.我不确定这是否可行.如果没有,我想知道原因.以下是关于Boost和STL实现的主要痛点以及我想要的内容:
首先,性能不是问题.内存分配,虚函数调用,O(n)复杂度 - 无所谓.无论如何,每天的词典只有几个条目.易用性至关重要.
语法通常应该类似于数组.这意味着一个多功能的操作员[],如:
字典[key] =价值; //插入和更新字典[key] = NULL; //删除元素if(dictionary [key])//检查元素是否存在.不应插入默认构造的值!
Java和Objective-C没有运算符重载,所以这是不可能的.C#拥有它并充分利用它.C++不能这样做吗?
值和键都可以是自定义的用户定义类型或基本类型(整数,浮点数等).
存储用户定义的对象时,它们应该由shared_ptr引用.我正在使用Boost,所以这对于防止内存泄漏至关重要.其他三个平台要么是垃圾收集(C#/ Java),要么可以选择手动内存管理,引用计数和垃圾收集(目标C).Boost在实现引用计数方面做得很好,所以它应该是可能的.这正是Objective-C的NSDictionary在ARC开启的基础上制作的.
存储用户定义的对象时,默认情况下应根据内存地址对它们进行比较.非常重要:用户定义的对象不需要哈希函数,operator ==,operator <,公共基类等.需要这些东西可以明确地将比较从内存地址更改为其他内容,例如字符串的按值比较.但大多数时候我们只想要内存地址比较.
存储原始数据类型时,应按值进行比较.它们是否在某个内部对象中被包装/装箱应该与用户无关.再次,性能无关紧要.
使用if(dictionary [key])检查是否存在给定键的值.这不应该像在Boost和STL中那样插入默认的构造值对象.
应该为键和值强类型化.所以没有空虚*.此外,键和值都不需要公共基类,因为这会过于干扰并且会使第三方类更难以存储在地图中.
独特的钥匙.不允许空值(空值导致删除).
密钥应该可以作为向量或数组访问,并且可以通过索引进行遍历.迭代器需要太多输入.也就是说,我们应该能够写:
for(int i = 0; i <dictionary.getKeys().getCount(); i ++){shared_ptr value = dictionary [dictionary.getKeys()[i]]; }
必须编写充满迭代器声明的庞大for循环,这会使源代码的清晰度变得混乱.迭代器的typedef也不好,因为它们只会因为你遇到的每一个新的"Go To Definition"而增加复杂性,特别是在阅读别人的代码时.
我想我可以在列表中添加更多点数,但我会停在这里.您是否知道任何图书馆的地图类至少满足其中的大部分要点?我非常感谢任何建设性的反馈.