我写了这段代码:
(function ($, undefined) {
$.phone1.getCursorPosition = function() {
var el = $(this).get(0);
var pos = 0;
if('selectionStart' in el) {
pos = el.selectionStart;
} else if('selection' in document) {
el.focus();
var Sel = document.selection.createRange();
var SelLength = document.selection.createRange().text.length;
Sel.moveStart('character', -el.value.length);
pos = Sel.text.length - SelLength;
}
return pos;
}
})(jQuery);
$("#phone1").on('keypress', function(e){
var key = String.fromCharCode(e.which);
if(key === '*') {
var position = $(this).getCursorPosition();
console.log(position);
} else {
return false;
}
});
我正在使用firemonkey,因此当我在移动设备上运行时,我不会遇到问题,因为ARC将管理其生命周期。但是当我在Windows上时,这段代码是否安全?
我已经读过,我不能拥有一个finally和一个catch,所以我需要一个嵌套的try块。我想最好的方法就是:
FD := TList<double>.Create;
FN := TList<double>.Create;
RemList := TList<double>.Create;
dati := TStringList.Create;
try
try
//code
except
on E : Exception do
ShowMessage('Incorrect values. Error: ' + E.Message);
end;
finally
if Assigned(dati) then
dati.Free;
if Assigned(FD) then
FD.Free;
if Assigned(FN) then
FN.Free;
if Assigned(RemList) then
RemList.Free;
end;
我相信我会在任何情况下以安全的方式释放对象,但代码很难阅读。我已经看到Marco Cantu建议在对象pascal手册中使用第二种方法并且我理解它,但在我的情况下我想避免它。
在我编写的第一个代码块中是否会出现错误?
答案 0 :(得分:2)
如果我是你,我会使用第二段代码,因为你已经知道它更好了; TList<double>.Create
(和其他构造函数一样)是&#34;安全&#34;如你所说,但如果你总是认为角落背后存在风险,那就更好了。
请注意,当我说 safe 时,我的意思是如果你以这种方式打电话,他们不会提出异常。在您无法预测的任何情况下都可能发生异常,因此您最终应该尝试保护代码。
您还在使用无用的Assigned()
。如果你看一下Free
的实现,你会发现这个代码(它也被评论过):
procedure TObject.Free;
begin
// under ARC, this method isn't actually called since the compiler translates
// the call to be a mere nil assignment to the instance variable, which then calls _InstClear
{$IFNDEF AUTOREFCOUNT}
if Self <> nil then
Destroy;
{$ENDIF}
end;
Assigned()
如果对象等于nil则返回true或false,所以基本上你做了无用的双重检查。
答案 1 :(得分:2)
虽然嵌套try...finally
的第二个代码最终以书方式处理对象构造/解构块,但您也可以安全地将它们分组到单个try...finally
块中。 / p>
一些可以帮助我们挤压上述代码的事实。
所以你的代码看起来像这样:
// initialize object references so we can safely use them
FN := nil;
FD := nil;
RemList := nil;
dati := nil;
try
FD := TList<double>.Create;
FN := TList<double>.Create;
RemList := TList<double>.Create;
dati := TStringList.Create;
// do something
finally
dati.Free;
FD.Free;
FN.Free;
RemList.Free;
end;
如果任何构造函数失败finally
将执行块,并且将清除所有已分配的引用。由于Free
在调用实例析构函数之前测试nil,因此在nil引用上调用它是安全的。
以上介绍了如何编写安全的施工/解构链。如果您的执行某些操作代码抛出异常,您可以使用try..except
块来处理它,就像您现在正在执行此操作一样。
请记住,上面的代码不处理从构造函数抛出的异常,它只是执行适当的清理。如果要处理可能的构造异常,则必须将代码包含在另一个try...except
块中,或者让它们传播到更高级别。