dan*_*ass 8 fonts cocoa webkit
WebView
通过WebEditingDelegate
一种机制,支持代理为WebView
(或私有WebHTMLView
)接收的各种动作实现自定义行为.当一个动作,如:
-(void)changeAttributes:(id)sender
Run Code Online (Sandbox Code Playgroud)
收到后WebHTMLView
,它被传递给委托方法:
-(BOOL)webView:(WebView *)webView doCommandBySelector:(SEL)command
Run Code Online (Sandbox Code Playgroud)
不幸的是,该机制没有规定sender
在原始行动方法中传送" ".
对于绝大多数动作,发送者并不重要,但是对于changeAttributes和changeFont,例如,合同要求sender
接收者调用" "以便例如convertAttributes:
或者convertFont:
.
对于这种changeFont
情况,事实证明,呼叫[[NSFontManager sharedFontManager] convertFont:]
是足够的,因为巧合的是这是发送者.
在这种changeAttributes
情况下,特别是当删除线被改变时,发送者可以是私人类" NSFontEffectsBox
",其可能对应于负责改变删除线/等设置的字体面板的子部分.
不幸的是,调用[[NSFontManager sharedFontManager] convertAttributes:]
不会获得预期的属性更改.这使得有兴趣有意义地实现这种方法的代表有点困惑:
WebKit不传达发件人,因此代表不能进行合同[sender convertAttributes:]
调用.
该changeAttributes:
调用被发送到私有WebKit类,该类WebHTMLView
不能被子类化,例如,自定义其行为changeAttributes:
.
changeAttributes:
呼叫的发送方NSFontEffectsBox
是私有类,不能访问,例如[NSFontEffectsBox sharedFontEffectsBox]
.
简而言之:似乎有没有办法一个开发商有意义重写的行为changeAttributes:
的WebView
.
有任何想法吗?
这是一种邪恶的行为。一对适当邪恶的行为(它们都不是特别干净或理想的)将是:
执行一些内联汇编程序来查找堆栈,以从调用者的堆栈(或调用者的调用者,视情况而定)中读取发送者参数。当然,这假设发送者被放置在堆栈上,而不是在%eax
调用时放置在堆栈上WebHTMLView
。然而,这将始终适用于 PowerPC 代码,因此它可能是一个行不通的人。
WebHTMLView
使用名为类似名称的方法放置一个类别__my_evil_hacky_nasty_ugly_changeAttributes_thing:
,并在运行时使用 ObjC 运行时中的 method_exchangeImplementations() 将您的类别的实现与他们的实现交换。你的方法变成了,changeAttributes:
他们的方法变成了__my_evil_hacky_nasty_ugly_changeAttributes_thing:
,然后你可以调用它来传递原始调用。
正如我所说,两者都不是特别理想,但第二个具有完整运行时支持的优势(即运行时明确设计为让您执行此操作),并且由于您在运行时查找类和方法,所以它是失败的 -宽容。然而,在这种情况下失败会让你回到原点。
实际上,它需要针对 WebKit 记录一个错误,让它们传递给发件人,使其变得有意义。您的重写版本可能会查找方法-(BOOL)webView:(WebView*)webView doCommandBySelector:(SEL)selector sender:(id)sender
并在找到时调用该方法,否则只需调用原始方法。老实说,这就是苹果代码应该做的事情。
归档时间: |
|
查看次数: |
1523 次 |
最近记录: |