Skip to main content
 首页 » 编程设计

c#之UIColor 子类中的工厂方法导致崩溃

2025年12月25日30mq0036

我正在涉足 Android 的 MonoTouch/Mono,目前正在创建我自己的 UIColor 子类。不知何故,我无法让我的工厂方法以我想要的方式工作(但我确实有一个解决方法)。

以下代码导致我崩溃:

using System; 
 
#if ANDROID 
// TODO: T.B.I. 
#else  
using MonoTouch.UIKit; 
#endif 
 
namespace OurCompany.Core 
{ 
    public class Color : UIColor 
    { 
        public Color (float r, float g, float b, float a) : base(r, g, b, a) 
        { 
        } 
 
        // our webservice sends color strings in the following ugly format: 
        //  0,255,100,1.0 
        public static Color FromColorString (string colorString) 
        { 
            var comps = colorString != null ? colorString.Split (new char[] {','}) : null; 
            if (comps == null || comps.Length != 4) { 
                return null; 
            } 
 
            float r = 0.0f, g = 0.0f, b = 0.0f, a = 1.0f; 
 
            float.TryParse (comps [0], out r); 
            float.TryParse (comps [1], out g); 
            float.TryParse (comps [2], out b); 
            float.TryParse (comps [3], out a); 
 
            return new Color (r, g, b, a); 
        } 
    } 
} 

当我将 return 语句更改为以下内容时,我没有遇到任何崩溃:

return (Color)UIColor.FromRGBA ( 
    r > 0 ? r / 255 : 0.0f, 
    g > 0 ? g / 255 : 0.0f, 
    b > 0 ? b / 255 : 0.0f, 
    a 
); 

此返回语句的主要区别在于创建了一个 UIColor 对象并将其类型转换为一个 Color 对象,而在崩溃版本中,我使用我的参数实例化了一个 Color 对象。以这种方式实例化基类时可能出现问题?我很困惑。

最后是崩溃的堆栈跟踪:

堆栈跟踪:
  at (wrapper managed-to-native) MonoTouch.ObjCRuntime.Messaging.IntPtr_objc_msgSendSuper (intptr,intptr) <IL 0x00026, 0xffffffff> 
  at MonoTouch.UIKit.UIColor.get_CGColor () [0x00021] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIColor.g.cs:476 
  at MonoTouch.UIKit.UIColor.GetRGBA (single&,single&,single&,single&) [0x00000] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIColor.cs:51 
  at MonoTouch.UIKit.UIColor.ToString () [0x00000] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIColor.cs:141 
  at string.FormatHelper (System.Text.StringBuilder,System.IFormatProvider,string,object[]) [0x00168] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/String.cs:1890 
  at string.Format (System.IFormatProvider,string,object[]) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/String.cs:1820 
  at string.Format (string,object[]) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/String.cs:1815 
  at OurCompany.Core.AppDefaults.ToString () [0x00000] in /Volumes/Development/Mono/OurCompany/OurCompany.Core.Cloned/DL/AppDefaults.cs:78 
  at string.FormatHelper (System.Text.StringBuilder,System.IFormatProvider,string,object[]) [0x00168] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/String.cs:1890 
  at string.Format (System.IFormatProvider,string,object[]) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/String.cs:1820 
  at string.Format (string,object) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/String.cs:1800 
  at System.IO.TextWriter.Write (string,object) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.IO/TextWriter.cs:191 
  at System.IO.TextWriter.WriteLine (string,object) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.IO/TextWriter.cs:305 
  at System.IO.SynchronizedWriter.WriteLine (string,object) [0x0000c] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.IO/TextWriter.cs:598 
  at System.Console.WriteLine (string,object) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Console.cs:459 
  at OurCompany.Core.AppDefaults..ctor (System.IO.MemoryStream) [0x0012b] in /Volumes/Development/Mono/OurCompany/OurCompany.Core.Cloned/DL/AppDefaults.cs:73 
  at OurCompany.Core.HomeScreenService/<LoadAppDefaultsAsync>c__AnonStorey2.<>m__2 (byte[],System.Exception) [0x0000f] in /Volumes/Development/Mono/OurCompany/OurCompany.Core.Cloned/SAL/HomeScreenService.cs:47 
  at OurCompany.Core.ServiceRequest/<LoadRequestAsync>c__AnonStorey4.<>m__4 (object,System.Net.DownloadDataCompletedEventArgs) [0x00022] in /Volumes/Development/Mono/OurCompany/OurCompany.Core.Cloned/SAL/ServiceRequest.cs:31 
  at System.Net.WebClient.OnDownloadDataCompleted (System.Net.DownloadDataCompletedEventArgs) [0x00011] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/WebClient.cs:1388 
  at System.Net.WebClient.<DownloadDataAsync>m__D (object) [0x00019] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/WebClient.cs:1037 
  at System.Threading.Thread.StartInternal () [0x00032] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Threading/Thread.cs:699 
  at (wrapper runtime-invoke) object.runtime_invoke_void__this__ (object,intptr,intptr,intptr) <IL 0x0004e, 0xffffffff> 

native 堆栈跟踪:
0   OurCompanyiOS                         0x0009148c mono_handle_native_sigsegv + 284 
1   OurCompanyiOS                         0x00005568 mono_sigsegv_signal_handler + 248 
2   libsystem_c.dylib                   0x99d7686b _sigtramp + 43 
3   ???                                 0xffffffff 0x0 + 4294967295 
4   CoreFoundation                      0x012c3ae0 __CFStringAppendFormatCore + 16208 
5   CoreFoundation                      0x012bfaab CFStringCreateWithFormatAndArguments + 107 
6   CoreFoundation                      0x01348da1 +[NSException raise:format:] + 65 
7   UIKit                               0x028f7f34 -[UIColor CGColor] + 82 
8   ???                                 0x100a2743 0x0 + 269100867 
9   ???                                 0x140ee158 0x0 + 336519512 
10  ???                                 0x140edcbc 0x0 + 336518332 
11  ???                                 0x140eda18 0x0 + 336517656 
12  ???                                 0x0fbf703a 0x0 + 264204346 
13  ???                                 0x13e03a8c 0x0 + 333462156 
14  ???                                 0x140e9394 0x0 + 336499604 
15  ???                                 0x140e90c8 0x0 + 336498888 
16  ???                                 0x0fbf703a 0x0 + 264204346 
17  ???                                 0x13e03a8c 0x0 + 333462156 
18  ???                                 0x13ecd1b0 0x0 + 334287280 
19  ???                                 0x13ecd110 0x0 + 334287120 
20  ???                                 0x13ecd0a7 0x0 + 334287015 
21  ???                                 0x13eccffe 0x0 + 334286846 
22  ???                                 0x13eccf68 0x0 + 334286696 
23  ???                                 0x13ebb838 0x0 + 334215224 
24  ???                                 0x13ebb0c8 0x0 + 334213320 
25  ???                                 0x13ea481a 0x0 + 334120986 
26  ???                                 0x13ea42e9 0x0 + 334119657 
27  ???                                 0x13e167f2 0x0 + 333539314 
28  ???                                 0x13e150d7 0x0 + 333533399 
29  ???                                 0x0fbf4070 0x0 + 264192112 
30  OurCompanyiOS                         0x00009922 mono_jit_runtime_invoke + 722 
31  OurCompanyiOS                         0x0016c4ae mono_runtime_invoke + 126 
32  OurCompanyiOS                         0x0016c61c mono_runtime_delegate_invoke + 140 
33  OurCompanyiOS                         0x001a7522 start_wrapper + 466 
34  OurCompanyiOS                         0x001d94ba thread_start_routine + 154 
35  OurCompanyiOS                         0x002008ad GC_start_routine + 93 
36  libsystem_c.dylib                   0x99d8a557 _pthread_start + 344 
37  libsystem_c.dylib                   0x99d74cee thread_start + 34 
 
================================================================= 
Got a SIGSEGV while executing native code. This usually indicates 
a fatal error in the mono runtime or one of the native libraries  
used by your application. 
================================================================= 

请您参考如下方法:

好吧,我意识到我做错了什么,我应该更清楚地检查错误信息。

我的 AppDefaults 类具有以下 ToString() 方法(由 MonoDevelop 自动完成,并且可能仍然依赖于我之前的 UIColor 实现):

public override string ToString () 
{ 
    return string.Format ("[AppDefaults: name={0}, appId={1}, userId={2}, themeId={3}, parallaxEnabled={4}, themeModifyDate={5}, tabBarColor={6}, tabColor={7}, backButtonColor={8}]", name, appId, userId, themeId, parallaxEnabled, themeModifyDate, tabBarColor, tabColor, backButtonColor); 
} 

错误消息还显示了尝试为颜色类写入字符串值时发生错误的提示:
at MonoTouch.UIKit.UIColor.GetRGBA (single&,single&,single&,single&) [0x00000] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIColor.cs:51 
at MonoTouch.UIKit.UIColor.ToString () [0x00000] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIColor.cs:141 
at string.FormatHelper (System.Text.StringBuilder,System.IFormatProvider,string,object[]) [0x00168] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/String.cs:1890 

所以最终修复很简单:禁用我的 ToString()类中的方法。我讨厌我在这个明显的错误上浪费了 6 个小时,但是在使用新框架时总是会发生这样的事情......

编辑:也许我也可以覆盖我的 ToString()我的自定义 Color 子类中的方法,尽管这本身似乎并不能防止崩溃。我确实意识到,如果某个随机的人会使用此代码,我需要防止将来发生这种崩溃。

编辑 2:查看崩溃日志,似乎初始化可能无法正常工作。我看到很多 null值(0x000 ....)。调用 GetRGBA() 时出现问题。也许我需要覆盖 UIColor 的一些成员使此方法起作用的基类?我可以想象 GetRGBA()正在调用我的自定义 Color类而不是 UIColor基类,导致失败。

编辑 3:这个人可能为我的问题选择了更好的方法。也许这将是我需要的修复:

http://codebetter.com/petervanooijen/2010/09/28/monotouch-drawing-an-image-pixel-by-pixel/

编辑 4:我决定根据最后一个链接重构我的代码。我的自定义颜色类将存储颜色的属性并具有 1 个或多个方法来创建 native 颜色对象(例如 iOS 上的 UIColor,Android 上的相应颜色对象)。