serializedname?characterized
很多朋友对于serializedname和characterized不太懂,今天就由小编来为大家分享,希望可以帮助到大家,下面一起来看看吧!
referer 是什么意思
HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理。比如从我主页上链接到一个朋友那里,他的服务器就能够从HTTP Referer中统计出每天有多少用户点击我主页上的链接访问他的网站。
在JSP中获取REFERER的方式是:request.getHeader("REFERER");
refit默认windows启动
refit默认windows启动()1.简介Refit是一个受到Square的Retrofit库(Java)启发的自动类型安全REST库。通过HttpClient网络请求(POST,GET,PUT,DELETE等封装)把REST API返回的数据转化为POCO(Plain Ordinary C# Object,简单C#对象) to JSON。我们的应用程序通过Refit请求网络,实际上是使用Refit接口层封装请求参数、Header、Url等信息,之后由HttpClient完成后续的请求操作,在服务端返回数据之后,HttpClient将原始的结果交给Refit,后者根据用户的需求对结果进行解析的过程。安装组件命令行:
Install-Package refit代码例子:
[Headers("User-Agent: Refit Integration Tests")]//这里因为目标源是GitHubApi,所以一定要加入这个静态请求标头信息,让其这是一个测试请求,不然会返回数据异常。public interface IGitHubApi{ [Get("/users/{user}")] Task GetUser(string user);}public class GitHubApi{ public async Task GetUser(){ var gitHubApi= RestService.For(""); var octocat= await gitHubApi.GetUser("octocat"); return octocat;}}public class User{ public string login{ get; set;} public int? id{ get; set;} public string url{ get; set;}}[HttpGet]public async Task<ActionResult<IEnumerable>> Get(){ var result= await new GitHubApi().GetUser(); return new string[]{ result.id.Value.ToString(), result.login};}注:接口中Headers、Get这些属性叫做Refit的特性。定义上面的一个IGitHubApi的REST API接口,该接口定义了一个函数GetUser,该函数会通过HTTP GET请求去访问服务器的/users/{user}路径把返回的结果封装为User POCO对象并返回。其中URL路径中的{user}的值为GetUser函数中的参数user的取值,这里赋值为octocat。然后通过RestService类来生成一个IGitHubApi接口的实现并供HttpClient调用。
2.API属性
每个方法必须具有提供请求URL和HTTP属性。HTTP属性有六个内置注释:Get, Post, Put, Delete, Patch and Head,例:
[Get("/users/list")]您还可以在请求URL中指定查询参数:
[Get("/users/list?sort=desc")]还可以使用相对URL上的替换块和参数来动态请求资源。替换块是由{and,即&}包围的字母数字字符串。如果参数名称与URL路径中的名称不匹配,请使用AliasAs属性,例:
[Get("/group/{id}/users")]Task<List> GroupList([AliasAs("id")] int groupId);请求URL还可以将替换块绑定到自定义对象,例:
[Get("/group/{request.groupId}/users/{request.userId}")]Task<List> GroupList(UserGroupRequest request);class UserGroupRequest{ int groupId{ get;set;} int userId{ get;set;}}未指定为URL替换的参数将自动用作查询参数。这与Retrofit不同,在Retrofit中,必须明确指定所有参数,例:
[Get("/group/{id}/users")]Task<List> GroupList([AliasAs("id")] int groupId, [AliasAs("sort")] string sortOrder);GroupList(4,"desc");输出结果:"/group/4/users?sort=desc"
3.动态查询字符串参数(Dynamic Querystring Parameters)
方法还可以传递自定义对象,把对象属性追加到查询字符串参数当中,例如:
public class MyQueryParams{ [AliasAs("order")] public string SortOrder{ get; set;} public int Limit{ get; set;}}[Get("/group/{id}/users")]Task<List> GroupList([AliasAs("id")] int groupId, MyQueryParams params);[Get("/group/{id}/users")]Task<List> GroupListWithAttribute([AliasAs("id")] int groupId, [Query(".","search")]MyQueryParams params);params.SortOrder="desc";params.Limit= 10;GroupList(4, params)输出结果:"/group/4/users?order=desc&Limit=10"
GroupListWithAttribute(4, params)输出结果:"/group/4/users?search.order=desc&search.Limit=10"您还可以使用[Query]指定querystring参数,并将其在非GET请求中扁平化,类似于:
[Post("/statuses/update.json")]Task PostTweet([Query]TweetParams params);5.集合作为查询字符串参数(Collections as Querystring Parameters)方法除了支持传递自定义对象查询,还支持集合查询的,例:
[Get("/users/list")]Task Search([Query(CollectionFormat.Multi)]int[] ages);Search(new []{10, 20, 30})输出结果:"/users/list?ages=10&ages=20&ages=30"
[Get("/users/list")]Task Search([Query(CollectionFormat.Csv)]int[] ages);Search(new []{10, 20, 30})输出结果:"/users/list?ages=10%2C20%2C30"
6.转义符查询字符串参数(Unescape Querystring Parameters)
使用QueryUriFormat属性指定查询参数是否应转义网址,例:
[Get("/query")][QueryUriFormat(UriFormat.Unescaped)]Task Query(string q);Query("Select+Id,Name+From+Account")输出结果:"/query?q=Select+Id,Name+From+Account"
7.Body内容
通过使用Body属性,可以把自定义对象参数追加到HTTP请求Body当中。
[Post("/users/new")]Task CreateUser([Body] User user)根据参数的类型,提供Body数据有四种可能性:●如果类型为Stream,则内容将通过StreamContent流形式传输。●如果类型为string,则字符串将直接用作内容,除非[Body(BodySerializationMethod.Json)]设置了字符串,否则将其作为StringContent。●如果参数具有属性[Body(BodySerializationMethod.UrlEncoded)],则内容将被URL编码。●对于所有其他类型,将使用RefitSettings中指定的内容序列化程序将对象序列化(默认为JSON)。●缓冲和Content-Length头默认情况下,Refit重新调整流式传输正文内容而不缓冲它。例如,这意味着您可以从磁盘流式传输文件,而不会产生将整个文件加载到内存中的开销。这样做的缺点是没有在请求上设置内容长度头(Content-Length)。如果您的API需要您随请求发送一个内容长度头,您可以通过将[Body]属性的缓冲参数设置为true来禁用此流行为:
Task CreateUser([Body(buffered: true)] User user);7.1.JSON内容使用Json.NET对JSON请求和响应进行序列化/反序列化。默认情况下,Refit将使用可以通过设置Newtonsoft.Json.JsonConvert.DefaultSettings进行配置的序列化器设置:
JsonConvert.DefaultSettings=()=> new电脑 JsonSerializerSettings(){ ContractResolver= new CamelCasePropertyNamesContractResolver(), Converters={new StringEnumConverter()}};//Serialized as:{"day":"Saturday"}await PostSomeStuff(new{ Day= DayOfWeek.Saturday});由于默认静态配置是全局设置,它们将影响您的整个应用程序。有时候我们只想要对某些特定API进行设置,您可以选择使用RefitSettings属性,以允许您指定所需的序列化程序进行设置,这使您可以为单独的API设置不同的序列化程序设置:
var gitHubApi= RestService.For("", new RefitSettings{ ContentSerializer= new JsonContentSerializer( new JsonSerializerSettings{ ContractResolver= new SnakeCasePropertyNamesContractResolver()})});var otherApi= RestService.For("", new RefitSettings{ ContentSerializer= new JsonContentSerializer( new JsonSerializerSettings{电脑 ContractResolver= new CamelCasePropertyNamesContractResolver()})});还可以使用Json.NET的JsonProperty属性来自定义属性序列化/反序列化:
public class Foo{//像[AliasAs(“ b”)]一样会在表单中发布 [JsonProperty(PropertyName="b")] public string Bar{ get; set;}} 7.2XML内容XML请求和响应使用System.XML.Serialization.XmlSerializer进行序列化/反序列化。默认情况下,Refit只会使用JSON将内容序列化,若要使用XML内容,请将ContentSerializer配置为使用XmlContentSerializer:
var gitHubApi= RestService.For("", new RefitSettings{ ContentSerializer= new XmlContentSerializer()});属性序列化/反序列化可以使用System.Xml.serialization命名空间中的属性进行自定义:
public class Foo{ [XmlElement(Namespace="")] public string Bar{ get; set;}}System.Xml.Serialization.XmlSerializer提供了许多序列化选项,可以通过向XmlContentSerializer构造函数提供XmlContentSerializer设置来设置这些选项:
var电脑 gitHubApi= RestService.For("", new RefitSettings{ ContentSerializer= new XmlContentSerializer( new XmlContentSerializerSettings{ XmlReaderWriterSettings= new XmlReaderWriterSettings(){ ReaderSettings= new XmlReaderSettings{ IgnoreWhitespace= true}}})});7.3.表单发布(Form posts)对于以表单形式发布(即序列化为application/x-www-form-urlencoded)的API,请使用初始化Body属性BodySerializationMethod.UrlEncoded属性,参数可以是IDictionary字典,例:
public interface IMeasurementProtocolApi{ [Post("/collect")] Task Collect([Body(BodySerializationMethod.UrlEncoded)] Dictionary data);}var data= new Dictionary{{"v", 1},{"tid","UA-1234-5"},{"cid", new Guid("d1e9ea6b-2e8b-4699-93e0-0bcbd26c206c")},{"t","event"},};// Serialized as: v=1&tid=UA-1234-5&cid=d1e9ea6b-2e8b-4699-93e0-0bcbd26c206c&t=eventawait api.Collect(data);如果我们传递对象跟请求表单中字段名称不一致时,可在对象属性名称上加入[AliasAs("你定义字段名称")]属性,那么加入属性的对象字段都将会被序列化为请求中的表单字段:
public interface IMeasurementProtocolApi{ [Post("/collect")] Task Collect([Body(BodySerializationMethod.UrlEncoded)] Measurement measurement);}public class Measurement{// Properties can be read-only and [AliasAs] isn't required public int v{ get{ return 1;}} [AliasAs("tid")] public string WebPropertyId{ get; set;} [AliasAs("cid")] public Guid ClientId{ get; set;} [AliasAs("t")] public string Type{ get; set;} public object IgnoreMe{ private get; set;}}var measurement= new Measurement{ WebPropertyId="UA-1234-5", ClientId= new Guid("d1e9ea6b-2e8b-4699-93e0-0bcbd26c206c"), Type="event"};// Serialized as: v=1&tid=UA-1234-5&cid=d1e9ea6b-2e8b-4699-93e0-0bcbd26c206c&t=eventawait api.Collect(measurement);8.设置请求头8.1静态头(Static headers)您可以为将headers属性应用于方法的请求设置一个或多个静态请求头:
[Headers("User-Agent: Awesome Octocat App")][Get("/users/{user}")]Task GetUser(string user);通过将headers属性应用于接口,还可以将静态头添加到API中的每个请求:
[Headers("User-Agent: Awesome Octocat App")]public interface IGitHubApi{ [Get("/users/{user}")] Task GetUser(string user); [Post("/users/new")] Task CreateUser([Body] User user);}8.2动态头(Dynamic headers)如果需要在运行时设置头的内容,则可以通过将头属性应用于参数来向请求添加具有动态值的头:
[Get("/users/{user}")]Task GetUser(string user, [Header("Authorization")] string authorization);// Will add the header"Authorization: token OAUTH-TOKEN" to the requestvar user= await GetUser("octocat","token OAUTH-TOKEN"); 8.3授权(动态头redux)使用头的最常见原因是为了授权。而现在大多数API使用一些oAuth风格的访问令牌,这些访问令牌会过期,刷新寿命更长的令牌。封装这些类型的令牌使用的一种方法是,可以插入自定义的HttpClientHandler。这样做有两个类:一个是AuthenticatedHttpClientHandler,它接受一个Func<Task>参数,在这个参数中可以生成签名,而不必知道请求。另一个是authenticatedparameteredhttpclienthandler,它接受一个Func<HttpRequestMessage,Task>参数,其中签名需要有关请求的信息(参见前面关于Twitter的API的注释),例如:
class AuthenticatedHttpClientHandler: HttpClientHandler{ private readonly Func<Task> getToken; public AuthenticatedHttpClientHandler(Func<Task> getToken){ if(getToken== null) throw new ArgumentNullException(nameof(getToken)); this.getToken= getToken;} protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken){// See if the request has an authorize header var auth= request.Headers.Authorization; if(auth!= null){ var token= await getToken().ConfigureAwait(false); request.Headers.Authorization= new AuthenticationHeaderValue(auth.Scheme, token);} return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);}}或者:
class AuthenticatedParameterizedHttpClientHandler: DelegatingHandler{ readonly Func<HttpRequestMessage, Task> getToken; public AuthenticatedParameterizedHttpClientHandler(Func<HttpRequestMessage, Task> getToken, HttpMessageHandler innerHandler= null): base(innerHandler?? new HttpClientHandler()){ this.getToken= getToken?? throw new ArgumentNullException(nameof(getToken));} protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken){// See if the request has an authorize header var auth= request.Headers.Authorization; if(auth!= null){ var token= await getToken(request).ConfigureAwait(false); request.Headers.Authorization= new AuthenticationHeaderValue(auth.Scheme, token);} return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);}}虽然HttpClient包含一个几乎相同的方法签名,但使用方式不同。重新安装未调用HttpClient.SendAsync。必须改为修改HttpClientHandler。此类的用法与此类似(示例使用ADAL库来管理自动令牌刷新,但主体用于Xamarin.Auth或任何其他库:
class LoginViewModel{ AuthenticationContext context= new AuthenticationContext(...); private async Task GetToken(){// The AcquireTokenAsync call will prompt with a UI if necessary// Or otherwise silently use a refresh token to return// a valid access token var token= await context.AcquireTokenAsync("","clientId", new Uri("callback://complete")); return token;} public async Task LoginAndCallApi(){ var api= RestService.For(new HttpClient(new AuthenticatedHttpClientHandler(GetToken)){ BaseAddress= new Uri("")}); var location= await api.GetLocationOfRebelBase();}}interface IMyRestService{ [Get("/getPublicInfo")] Task SomePublicMethod(); [Get("/secretStuff")] [Headers("Authorization: Bearer")] Task GetLocationOfRebelBase();}在上面的示例中,每当调用需要身份验证的方法时,AuthenticatedHttpClientHandler将尝试获取新的访问令牌。由应用程序提供,检查现有访问令牌的过期时间,并在需要时获取新的访问令牌。
电脑
unity profiler怎么看
打开unity- Window- profiler
-就算全部告诉你,你也不一定全都用的到。
A. WaitForTargetFPS:
Vsync(垂直同步)功能所,即显示当前帧的CPU等待时间
B. Overhead:
Profiler总体时间-所有单项的记录时间总和。用于记录尚不明确的时间消耗,以帮助进一步完善Profiler的统计。
C. Physics.Simulate:
当前帧物理模拟的CPU占用时间。
D. Camera.Render:
相机渲染准备工作的CPU占用量
E. RenderTexture.SetActive:
设置RenderTexture操作.
底层实现:1.比对当前帧与前一帧的ColorSurface和DepthSurface.
2.如果这两个Buffer一致则不生成新的RT,否则则生成新的RT,并设置与之相对应的Viewport和空间转换矩阵.
F. Monobehaviour.OnMouse_:
用于检测鼠标的输入消息接收和反馈,主要包括:SendMouseEvents和DoSendMouseEvents。(只要Edtor开起来,这个就会存在)
G. HandleUtility.SetViewInfo:
仅用于Editor中,作用是将GUI和Editor中的显示看起来与发布版本的显示一致。
H. GUI.Repaint:
GUI的重绘(说明在有使用原生的OnGUI)
I. Event.Internal_MakeMasterEventCurrent:
负责GUI的消息传送
J. Cleanup Unused Cached Data:
清空无用的缓存数据,主要包括RenderBuffer的垃圾回收和TextRendering的垃圾回收。
1.RenderTexture.GarbageCollectTemporary:存在于RenderBuffer的垃圾回收中,清除临时的FreeTexture.
2.TextRendering.Cleanup:TextMesh的垃圾回收操作
K. Application.Integrate Assets in Background:
遍历预加载的线程队列并完成加载,同时,完成纹理的加载、Substance的Update等.
L. Application.LoadLevelAsync Integrate:
加载场景的CPU占用,通常如果此项时间长的话70%的可能是Texture过长导致.
M. UnloadScene:
卸载场景中的GameObjects、Component和GameManager,一般用在切换场景时.
N. CollectGameObjectObjects:
执行上面M项的同时,会将场景中的GameObject和Component聚集到一个Array中.然后执行下面的Destroy.
O. Destroy:
删除GameObject和Component的CPU占用.
P. AssetBundle.LoadAsync Integrate:
多线程加载AwakeQueue中的内容,即多线程执行资源的AwakeFromLoad函数.
Q. Loading.AwakeFromLoad:
在资源被加载后调用,对每种资源进行与其对应用处理.
2. CPU Usage
A. Device.Present:
device.PresentFrame的耗时显示,该选项出现在发布版本中.
B. Graphics.PresentAndSync:
GPU上的显示和垂直同步耗时.该选项出现在发布版本中.
C. Mesh.DrawVBO:
GPU中关于Mesh的Vertex Buffer Object的渲染耗时.
D. Shader.Parse:
资源加入后引擎对Shader的解析过程.
E. Shader.CreateGPUProgram:
根据当前设备支持的图形库来建立GPU工程.
3. Memory Profiler
A. Used Total:
当前帧的Unity内存、Mono内存、GfxDriver内存、Profiler内存的总和.
B. Reserved Total:
系统在当前帧的申请内存.
C. Total System Memory Usage:
当前帧的虚拟内存使用量.(通常是我们当前使用内存的1.5~3倍)
D. GameObjects in Scene:
当前帧场景中的GameObject数量.
E. Total Objects in Scene:
当前帧场景中的Object数量(除GameObject外,还有Component等).
F. Total Object Count:
Object数据+ Asset数量.
4. Detail Memory Profiler
A. Assets:
Texture2d:记录当前帧内存中所使用的纹理资源情况,包括各种GameObject的纹理、天空盒纹理以及场景中所用的Lightmap资源.
B. Scene Memory:
记录当前场景中各个方面的内存占用情况,包括GameObject、所用资源、各种组件以及GameManager等(天般情况通过AssetBundle加载的不会显示在这里).
A. Other:
ManagedHeap.UseSize:代码在运行时造成的堆内存分配,表示上次GC到目前为止所分配的堆内存量.
SerializedFile(3):
WebStream:这个是由WWW来进行加载的内存占用.
System.ExecutableAndDlls:不同平台和不同硬件得到的值会不一样。
5.优化重点
A. CPU-GC Allow:
关注原则:1.检测任何一次性内存分配大于2KB的选项 2.检测每帧都具有20B以上内存分配的选项.
B. Time ms:
记录游戏运行时每帧CPU占用(特别注意占用5ms以上的).
C. Memory Profiler-Other:
1.ManagedHeap.UsedSize:移动游戏建议不要超过20MB.
2.SerializedFile:通过异步加载(LoadFromCache、WWW等)的时候留下的序列化文件,可监视是否被卸载.
3.WebStream:通过异步WWW下载的资源文件在内存中的解压版本,比SerializedFile大几倍或几十倍,重点监视.****
D. Memory Profiler-Assets:
1.Texture2D:重点检查是否有重复资源和超大Memory是否需要压缩等.
2.AnimationClip:重点检查是否有重复资源.
3.Mesh:重点检查是否有重复资源.
6.项目中可能遇到的问题
A. Device.Present:
1.GPU的presentdevice确实非常耗时,一般出现在使用了非常复杂的shader.
2.GPU运行的非常快,而由于Vsync的原因,使得它需要等待较长的时间.
3.同样是Vsync的原因,但其他线程非常耗时,所以导致该等待时间很长,比如:过量AssetBundle加载时容易出现该问题.
4.Shader.CreateGPUProgram:Shader在runtime阶段(非预加载)会出现卡顿(华为K3V2芯片).
B. StackTraceUtility.PostprocessStacktrace()和StackTraceUtility.ExtractStackTrace():
1.一般是由Debug.Log或类似API造成.
2.游戏发布后需将Debug API进行屏蔽.
C. Overhead:
1.一般情况为Vsync所致.
2.通常出现在Android设备上.
D. GC.Collect:
原因: 1.代码分配内存过量(恶性的) 2.一定时间间隔由系统调用(良性的).
占用时间:1.与现有Garbage size相关 2.与剩余内存使用颗粒相关(比如场景物件过多,利用率低的情况下,GC释放后需要做内存重排)
E. GarbageCollectAssetsProfile:
1.引擎在执行UnloadUnusedAssets操作(该操作是比较耗时的,建议在切场景的时候进行).
2.尽可能地避免使用Unity内建GUI,避免GUI.Repaint过渡GC Allow.
3.if(other.tag== GearParent.MogoPlayerTag)改为other.CompareTag(GearParent.MogoPlayerTag).因为other.tag为产生180B的GC Allow.
F.少用foreach,因为每次foreach为产生一个enumerator(约16B的内存分配),尽量改为for.
G. Lambda表达式,使用不当会产生内存泄漏.
H.尽量少用LINQ:
1.部分功能无法在某些平台使用.
2.会分配大量GC Allow.
I.控制StartCoroutine的次数:
1.开启一个Coroutine(协程),至少分配37B的内存.
2.Coroutine类的实例-- 21B.
3.Enumerator-- 16B.
J.使用StringBuilder替代字符串直接连接.
K.缓存组件:
1.每次GetComponent均会分配一定的GC Allow.
2.每次Object.name都会分配39B的堆内存.
serializedname和characterized的问题分享结束啦,以上的文章解决了您的问题吗?欢迎您下次再来哦!