当我看一些ios标题如何被翻译成delphi时,我可以看到例如
typedef void(^FIRMessagingConnectCompletion)(NSError * __nullable error);
已翻译:
FIRMessagingConnectCompletion = procedure(error: NSError) of object;
然而我不明白为什么不用 cdecl ; ?因为ios中的所有内容都必须使用cdecl;为什么它没有被翻译成:
FIRMessagingConnectCompletion = procedure(error: NSError) of object; cdecl;
注意/修改
要回答Remy和Rudy,让一切都清楚,我想从一个原始的Delphi源代码中找出一个问题的好例子
在delphi中我们声明了这个接口:
NSURLSessionTaskDelegate = interface(IObjectiveC)
['{C48E0AED-64F3-45A4-8D42-E3DB12F668E7}']
procedure URLSessionTaskWillPerformHTTPRedirectionNewRequestCompletionHandler(session: NSURLSession;
task: NSURLSessionTask; willPerformHTTPRedirection: NSHTTPURLResponse; newRequest: NSURLRequest;
completionHandler: TFoundationCompletionHandler7); cdecl;
end;
与
type
TFoundationCompletionHandler7 = procedure(param1: NSURLRequest) of object;
所以我决定像这样实现它:
TMyNSURLSessionTaskDelegate = class(TOCLocal, NSURLSessionTaskDelegate)
public
procedure URLSessionTaskWillPerformHTTPRedirectionNewRequestCompletionHandler(session: NSURLSession;
task: NSURLSessionTask; willPerformHTTPRedirection: NSHTTPURLResponse; newRequest: NSURLRequest;
completionHandler: TFoundationCompletionHandler7); cdecl;
end;
但是(你可以尝试自己)只要你做TMyNSURLSessionTaskDelegate.create就会收到错误TFoundationCompletionHandler7 = procedure(param1: NSURLRequest) of object; is not a valid ObjectiveC type
问题出在哪里?如何使用NSURLSessionTaskDelegate?
答案 0 :(得分:1)
您为Delphi的NSURLSessionTaskDelegate
接口显示的声明与Apple's declaration of URLSessionTaskDelegate
不匹配,因此不能在Objective-C中按原样使用。这就是编译器所抱怨的。
NSURLSessionTaskDelegate
参数使用的完成处理程序的类型应该更像这样:
TFoundationCompletionHandler6 = procedure(param1: NSURLSessionAuthChallengeDisposition; param2: NSURLCredential); cdecl;
TFoundationCompletionHandler7 = procedure(request: NSURLRequest); cdecl;
TFoundationNeedNewBodyStream = procedure(param1: NSInputStream); cdecl;
(of object
替换为cdecl
)
在转换iOS标题时,这显然是Embarcadero的一个错误(坦率地说,我很惊讶它通过测试而没有被发现)。
然后,您将实现您的委托类:
type
TMyUrlSessionHTTPRedirection = procedure(
session: NSURLSession; task: NSURLSessionTask;
willPerformHTTPRedirection: NSHTTPURLResponse;
var newRequest: NSURLRequest) of object;
TMyNSURLSessionTaskDelegate = class(TOCLocal, NSURLSessionTaskDelegate)
public
OnHttpRedirection: TMyUrlSessionHTTPRedirection;
...
procedure URLSessionTaskWillPerformHTTPRedirectionNewRequestCompletionHandler(
session: NSURLSession; task: NSURLSessionTask;
willPerformHTTPRedirection: NSHTTPURLResponse; newRequest: NSURLRequest;
completionHandler: TFoundationCompletionHandler7); cdecl;
...
end;
procedure TMyNSURLSessionTaskDelegate.URLSessionTaskWillPerformHTTPRedirectionNewRequestCompletionHandler(
session: NSURLSession; task: NSURLSessionTask;
willPerformHTTPRedirection: NSHTTPURLResponse; newRequest: NSURLRequest;
completionHandler: TFoundationCompletionHandler7); cdecl;
var
finalRequest: NSURLRequest;
begin
finalRequest := newRequest;
if Assigned(OnHttpRedirection) then
OnHttpRedirection(session, task, willPerformHTTPRedirection, finalRequest);
completionHandler(finalRequest);
end;
然后,您将创建TMyNSURLSessionTaskDelegate
的实例,并为OnHttpRedirection
成员分配Delphi对象方法,然后将委托实例传递给iOS。在适当的时候,它会调用委托的urlSession()
方法,该方法将调用OnHttpRedirection
处理程序。
在Embarcadero修复他们的错误之前,您必须使用正确的类型声明在您自己的代码中重新声明NSURLSessionTaskDelegate
接口。
答案 1 :(得分:0)
它的工作原理如下:
FIRMessagingConnectCompletion
方法(没有cdecl
的方法)。 Delphi方法中的代码完全在Delphi中,并在Delphi上下文中运行。最初的iOS对象永远不会看到它,也不需要。of object
,就像一个事件,并且没有被声明为cdecl
,因为它完全在Delphi环境中运行。声明与原始声明非常相似,使其看起来好像正在实现回调,但实际上您正在实现Delphi事件。这样可以更轻松地翻译iOS示例和其他iOS代码,尽管底层类型/代码和基础结构完全不同。