我正在为Socket Rocket中的竞争条件进行修复。 很久以前就报告过这个错误,但仍然没有修复。
一年多以前,我已经编写了一个破解API的修复程序(只能使用共享线程),并且这个代码在生产时成功运行(当有很多用户时根本没有崩溃)。
现在我想以这样的方式调整我的修补程序,它不会破坏SRWebSocket
的API。
为此,我需要找到匹配NSThread
原谅NSRunLoop
。这是一对一的关系,但我找到一个可以帮助我的API有问题。
<小时/> PS。修复非常简单。在
NSRunLoop
上进行的每个操作都必须从相应的线程完成。没有NSRunLoop
或CFRunLoop API that can be safely used from another thread. So I've added such API to
SRRunLoopThread`:
- (void)scheduleBlock: (void(^)())block
{
[self performSelector: @selector(_runBlock:)
onThread: self
withObject: [block copy]
waitUntilDone: NO];
}
- (void)_runBlock: (void(^)())block
{
block();
}
并在NSRunLoop
上完成某些事情的地方使用它。
此修复程序显示了我需要找到匹配的NSThread
。
注意documentations表明performSelector:onThread:withObject:waitUntilDone:
是线程安全的
您可以使用此方法将消息传递到应用程序中的其他线程。
我必须再次强调NSRunLoop
CFRunLoop
API没有线程安全:
警告
NSRunLoop 类通常不被认为是线程安全的 它的方法只能在当前的上下文中调用 线。你永远不应该试着调用 NSRunLoop 的方法 对象在不同的线程中运行,因为这样做可能会导致 意想不到的结果。
由于NSRunLoop
与通过public class CustomImageView extends ImageView {
public static float radius = 25.0f;
public CustomImageView(Context context) {
super(context);
}
public CustomImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onDraw(Canvas canvas) {
//float radius = 36.0f;
Path clipPath = new Path();
RectF rect = new RectF(0, 0, this.getWidth(), this.getHeight());
clipPath.addRoundRect(rect, radius, radius, Path.Direction.CW);
canvas.clipPath(clipPath);
super.onDraw(canvas);
}}
桥接到/从 <your package name.CustomImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/thumbimg"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:visibility="gone"
/>
无关,所以它具有完全相同的弱点。
因此,如果文档没有说它是线程安全的API,那么它没有线程安全,我无法在该上下文中使用它(所以@DisableR提出的答案显然无效)。
答案 0 :(得分:1)
您可以执行具有runloop的块而无需线程。 块将在与运行循环相关联的线程上异步执行。
CFRunLoopPerformBlock([myNSRunLoop getCFRunLoop], kCFRunLoopCommonModes, block);
CFRunLoopWakeUp([myNSRunLoop getCFRunLoop]);
以下是关于macOS Tiger上-performSelectorOnMainThread:
NSThread
方法的实现的讨论,该方法不可用,问题与您的问题非常相似:
http://www.cocoabuilder.com/archive/cocoa/112261-cfrunlooptimer-firing-delay.html