GVKun编程网logo

delphi – 我得到RTTIMethod.Visibility = mvPublic用于私有记录方法. – 虫子?(虫字旁的字)

9

如果您想了解delphi–我得到RTTIMethod.Visibility=mvPublic用于私有记录方法.–虫子?的相关知识,那么本文是一篇不可错过的文章,我们将对虫字旁的字进行全面详尽的解释,并

如果您想了解delphi – 我得到RTTIMethod.Visibility = mvPublic用于私有记录方法. – 虫子?的相关知识,那么本文是一篇不可错过的文章,我们将对虫字旁的字进行全面详尽的解释,并且为您提供关于add a private constructor to hide the implicit public one(Utility classes should not have public ...、android – setVisibility()什么时候不在视图中触发onVisibilityChanged()?、android – View.setVisibility(View.VISIBLE)是否强制视图重绘,即使它已经可见?、Android 中 visibility 属性 VISIBLE、INVISIBLE、GONE 的区别的有价值的信息。

本文目录一览:

delphi – 我得到RTTIMethod.Visibility = mvPublic用于私有记录方法. – 虫子?(虫字旁的字)

delphi – 我得到RTTIMethod.Visibility = mvPublic用于私有记录方法. – 虫子?(虫字旁的字)

我使用Delphi 10.2获得了RTTIMethod.Visibility = mvPublic(严格)私有记录方法.这是一个错误吗?

更新2017-07-12:已创建问题:RSP-18587.

程序输出显示记录和类的所有实例成员类型和可见性;从RTTI返回的可见性;在TSomeRec中查看PrivateProcedure:

Types:
  Unit1.TSomeRec
    Fields:
      PrivateField
        Visibility: mvPrivate
      PublicField
        Visibility: mvPublic
    Properties:
    Methods:
      PrivateProcedure
        Visibility: mvPublic
      PrivateFunction
        Visibility: mvPublic
      PublicProcedure
        Visibility: mvPublic
      PublicFunction
        Visibility: mvPublic
  Unit1.TSomeClass
    Fields:
      PrivateField
        Visibility: mvPrivate
      ProtectedField
        Visibility: mvProtected
      PublicField
        Visibility: mvPublic
    Properties:
      PrivateProperty
        Visibility: mvPrivate
      ProtectedProperty
        Visibility: mvProtected
      PublicProperty
        Visibility: mvPublic
      PublishedProperty
        Visibility: mvPublished
    Methods:
      PrivateProcedure
        Visibility: mvPrivate
      PrivateFunction
        Visibility: mvPrivate
      ProtectedProcedure
        Visibility: mvProtected
      ProtectedFunction
        Visibility: mvProtected
      PublicProcedure
        Visibility: mvPublic
      PublicFunction
        Visibility: mvPublic
      PublishedProcedure
        Visibility: mvPublished
      PublishedFunction
        Visibility: mvPublished

Unit1.pas:

unit Unit1;

interface

{$RTTI explicit
  Methods ([vcPrivate,vcProtected,vcpublic,vcpublished])
  Properties ([vcPrivate,vcpublished])
  Fields ([vcPrivate,vcpublished])
}

{$Region 'TSomeRec'}

type
  TSomeRec = record
  strict private
    PrivateField: Boolean;
    property PrivateProperty: Boolean read PrivateField;
    procedure PrivateProcedure;
    function PrivateFunction: Boolean;

  public
    PublicField: Boolean;
    property PublicProperty: Boolean read PublicField;
    procedure PublicProcedure;
    function PublicFunction: Boolean;
  end;

{$EndRegion}
{$Region 'TSomeClass'}

type
  TSomeClass = class
  strict private
    PrivateField: Boolean;
    property PrivateProperty: Boolean read PrivateField;
    procedure PrivateProcedure;
    function PrivateFunction: Boolean;

  strict protected
    ProtectedField: Boolean;
    property ProtectedProperty: Boolean read ProtectedField;
    procedure ProtectedProcedure;
    function ProtectedFunction: Boolean;

  public
    PublicField: Boolean;
    property PublicProperty: Boolean read PublicField;
    procedure PublicProcedure;
    function PublicFunction: Boolean;

  published
    property PublishedProperty: Boolean read PublicField;
    procedure PublishedProcedure;
    function PublishedFunction: Boolean;
  end;

{$EndRegion}

implementation

{$Region 'TSomeRec'}

{ TSomeRec }

function TSomeRec.PrivateFunction: Boolean;
begin
  Result := False;
end;

procedure TSomeRec.PrivateProcedure;
begin
end;

function TSomeRec.PublicFunction: Boolean;
begin
  Result := False;
end;

procedure TSomeRec.PublicProcedure;
begin
end;

{$EndRegion}
{$Region 'TSomeClass'}

{ TSomeClass }

function TSomeClass.PrivateFunction: Boolean;
begin
  Result := False;
end;

procedure TSomeClass.PrivateProcedure;
begin
end;

function TSomeClass.ProtectedFunction: Boolean;
begin
  Result := False;
end;

procedure TSomeClass.ProtectedProcedure;
begin
end;

function TSomeClass.PublicFunction: Boolean;
begin
  Result := False;
end;

procedure TSomeClass.PublicProcedure;
begin
end;

function TSomeClass.PublishedFunction: Boolean;
begin
  Result := False;
end;

procedure TSomeClass.PublishedProcedure;
begin
end;

{$EndRegion}

end.

Project1.dpr:

program Project1;

{$AppType Console}

{$R *.res}

uses
  System.RTTI,System.StrUtils,System.SysUtils,System.TypInfo,Unit1 in 'Unit1.pas';

{$Region 'IWriter,TWriter'}

type
  IWriter = interface
    procedure BeginSection(const Value: String = '');
    procedure EndSection;
    procedure WriteMemberSection(const Value: TRTTIMember);
  end;

  TWriter = class (TInterfacedobject,IWriter)
  strict private
    FIndentCount: NativeInt;

  strict protected
    procedure BeginSection(const Value: String);
    procedure EndSection;
    procedure WriteLn(const Value: String);
    procedure WriteMemberSection(const Value: TRTTIMember);

  public
  const
    IndentStr = '  ';
  end;

{ TWriter }

procedure TWriter.BeginSection(const Value: String);
begin
  WriteLn(Value);
  Inc(FIndentCount);
end;

procedure TWriter.EndSection;
begin
  Dec(FIndentCount);
end;

procedure TWriter.WriteLn(const Value: String);
begin
  System.WriteLn(Dupestring(IndentStr,FIndentCount) + Value);
end;

procedure TWriter.WriteMemberSection(const Value: TRTTIMember);
begin
  BeginSection(Value.Name);
  try
    WriteLn('Visibility: ' + TValue.From<TMemberVisibility>(Value.Visibility).ToString);
  finally
    EndSection;
  end;
end;

{$EndRegion}

{$Region '...'}

procedure Run;
var
  Writer: IWriter;
  RTTIContext: TRTTIContext;
  RTTIType: TRTTIType;
  RTTIField: TRTTIField;
  RTTIProp: TRTTIProperty;
  RTTIMethod: TRTTIMethod;
begin
  Writer := TWriter.Create;
  RTTIContext := TRTTIContext.Create;
  try
    RTTIContext.GetType(TypeInfo(TSomeRec));
    RTTIContext.GetType(TypeInfo(TSomeClass));
    Writer.BeginSection('Types:');
    for RTTIType in RTTIContext.GetTypes do
    begin
      if not RTTIType.Name.Contains('ISome')
        and not RTTIType.Name.Contains('TSome') then
        Continue;
      Writer.BeginSection(RTTIType.Qualifiedname);
      Writer.BeginSection('Fields:');
      for RTTIField in RTTIType.GetFields do
      begin
        if not RTTIField.Name.EndsWith('Field') then
          Continue;
        Writer.WriteMemberSection(RTTIField);
      end;
      Writer.EndSection;
      Writer.BeginSection('Properties:');
      for RTTIProp in RTTIType.GetProperties do
      begin
        if not RTTIProp.Name.EndsWith('Property') then
          Continue;
        Writer.WriteMemberSection(RTTIProp);
      end;
      Writer.EndSection;
      Writer.BeginSection('Methods:');
      for RTTIMethod in RTTIType.getmethods do
      begin
        if not RTTIMethod.Name.Contains('Procedure')
          and not RTTIMethod.Name.Contains('Function') then
          Continue;
        Writer.WriteMemberSection(RTTIMethod);
      end;
      Writer.EndSection;
      Writer.EndSection;
    end;
    Writer.EndSection;
  finally
    RTTIContext.Free;
  end;
end;

{$EndRegion}

begin
  {$Region '...'}
  try
    Run;
  except
    on E: Exception do
      WriteLn(E.ClassName,': ',E.Message);
  end;
  ReadLn;
  {$EndRegion}
end.

解决方法

问题是在TRttiRecordMethod中没有覆盖GetVisibility.我看了一下代码,有关可见性的信息实际上在Flag字段内.

所以类似于其他GetVisibility覆盖,例如在TRttiRecordField中,它需要实现.我把这报告为RSP-18588.

我写了一个小补丁,应该修复,如果你真的需要修复它(仅限Windows).

unit PatchRecordMethodGetVisibility;

interface

implementation

uses
  Rtti,SysUtils,TypInfo,Windows;

type
  TRec = record
    procedure Method;
  end;

procedure TRec.Method;
begin
end;

function GetVirtualMethod(AClass: TClass; const Index: Integer): Pointer;
begin
  Result := PPointer(UINT_PTR(AClass) + UINT_PTR(Index * SizeOf(Pointer)))^;
end;

procedure RedirectFunction(OrgProc,NewProc: Pointer);
type
  TJmpBuffer = packed record
    Jmp: Byte;
    Offset: Integer;
  end;
var
  n: UINT_PTR;
  JmpBuffer: TJmpBuffer;
begin
  JmpBuffer.Jmp := $E9;
  JmpBuffer.Offset := PByte(NewProc) - (PByte(OrgProc) + 5);
  if not WriteProcessMemory(GetCurrentProcess,OrgProc,@JmpBuffer,SizeOf(JmpBuffer),n) then
    RaiseLastOSError;
end;

type
  TRttiRecordMethodFix = class(TRttiMethod)
    function GetVisibility: TMemberVisibility;
  end;

procedure PatchIt;
var
  ctx: TRttiContext;
  recmethodCls: TClass;
begin
  recmethodCls := ctx.GetType(TypeInfo(TRec)).getmethod('Method').Classtype;
  RedirectFunction(GetVirtualMethod(recmethodCls,3),@TRttiRecordMethodFix.GetVisibility);
end;

{ TRttiRecordMethodFix }

function TRttiRecordMethodFix.GetVisibility: TMemberVisibility;

  function GetBitField(Value,Shift,Bits: Integer): Integer;
  begin
    Result := (Value shr Shift) and ((1 shl Bits) - 1);
  end;

const
  rmfVisibilityShift = 2;
  rmfVisibilityBits = 2;
begin
  Result := TMemberVisibility(GetBitField(PrecordtypeMethod(Handle)^.Flags,rmfVisibilityShift,rmfVisibilityBits))
end;

initialization
  PatchIt;

end.

add a private constructor to hide the implicit public one(Utility classes should not have public ...

add a private constructor to hide the implicit public one(Utility classes should not have public ...

sonarlint 提示 add a private constructor to hide the implicit public one

Utility classes should not have public constructors

Utility classes, which are collections of static members, are not meant to be instantiated. Even abstract utility classes, which can be extended, should not have public constructors.
Java adds an implicit public constructor to every class which does not define at least one explicitly. Hence, at least one non-public constructor should be defined.
Noncompliant Code Example
class StringUtils { // Noncompliant

  public static String concatenate(String s1, String s2) {
    return s1 + s2;
  }

}
Compliant Solution
class StringUtils { // Compliant

  private StringUtils() {
    throw new IllegalStateException("Utility class");
  }

  public static String concatenate(String s1, String s2) {
    return s1 + s2;
  }

}
Exceptions
When class contains public static void main(String[] args) method it is not considered as utility class and will be ignored by this rule.

 

意思是 util 类里面都是静态方法,不会去初始化这个类,所以不应该暴露一个 public 构造函数

解决方案:

     定义一个 private 构造函数

 

android – setVisibility()什么时候不在视图中触发onVisibilityChanged()?

android – setVisibility()什么时候不在视图中触发onVisibilityChanged()?

我有一个问题,在我在自定义视图中调用setVisibility(GONE)的特定情况下,它的onVisibilityChanged方法没有被调用,它实际上不会隐藏视图,尽管getVisibility()之后返回8(或GONE).

以下是我知道可见性更改的方法,但未调用onVisibilityChanged.

@Override
protected void onVisibilityChanged(@NonNull View changedView,int visibility) {
    Log.i(LOG_TAG,"onVisibilityChanged: " + visibility);
    super.onVisibilityChanged(changedView,visibility);
}

@Override
public void setVisibility(int visibility) {
    super.setVisibility(visibility);
    Log.i(LOG_TAG,"setVisibility: " + visibility);
}

public void hide(){
    Log.i(LOG_TAG,"before hide visibility: " + getVisibility());
    setVisibility(GONE);
    Log.i(LOG_TAG,"after hide visibility: " + getVisibility());
}

通常当我调用hide()时,我会在日志中看到这些行:

before hide visibility: 0

onVisibilityChanged: 8

setVisibility: 8

after hide visibility: 8

但是在一个特殊的情况下,当我调用hide()时,我在日志中得到这些行,之后视图不会被隐藏,尽管getVisibility()返回8:

before hide visibility: 0

setVisibility: 8

after hide visibility: 8

那么一般情况下会发生这种情况吗?什么时候setVisibility不调用onVisibilityChanged?

不要问我的具体情况是什么.但请提供可能发生这种情况的一般情况.

解决方法

只有在层次结构中附加视图时才会调用它.

对setVisibility的调用如下所示:

public void setVisibility(@Visibility int visibility) {
    setFlags(visibility,VISIBILITY_MASK);
}

setFlags方法是一个很长的方法,其中一组不同的视图属性被更改和处理,但值得注意的部分是:

if ((changed & VISIBILITY_MASK) != 0) {
      // if visiblity changed...
      ...
      if (mAttachInfo != null) { // true if attached in view hierarchy
            dispatchVisibilityChanged(this,newVisibility); // onVisibilityChanged is called from here 
            ...

因此,您将在未附加到片段或活动的视图上看到您描述的行为.

android – View.setVisibility(View.VISIBLE)是否强制视图重绘,即使它已经可见?

android – View.setVisibility(View.VISIBLE)是否强制视图重绘,即使它已经可见?

我正在试图找出我的自定义视图的优化.我想知道调用View.setVisibility(View.VISIBLE)是否强制Android框架更新视图可见性(< - 强制视图重绘),即使视图已经可见.

解决方法:

No, it doesn’t.

看看setVisibility():

public void setVisibility(int visibility) {
    setFlags(visibility, VISIBILITY_MASK);
    if (mBGDrawable != null) mBGDrawable.setVisible(visibility == VISIBLE, false);
}

它只是调用setFlags(),如果没有任何改变,它会立即返回:

....
int changed = mViewFlags ^ old;
if (changed == 0) {
    return;
}

即使它(某种程度上)已经过去了,它也会检查各个标志是否发生变化,只有在其中一个标志不同时才会更新.

Android 中 visibility 属性 VISIBLE、INVISIBLE、GONE 的区别

Android 中 visibility 属性 VISIBLE、INVISIBLE、GONE 的区别

在 Android 开发中,大部分控件都有 visibility 这个属性,其属性有 3 个分别为 “visible”、“invisible”、“gone”。主要用来设置控制控件的显示和隐藏。有些人可能会疑惑 Invisible 和 gone 是有什么区别的???那么,我们带着这个疑问看下面:

其在 XML 文件和 Java 代码中设置如下:

 

 

可见(visible)

XML 文件:android:visibility="visible"

Java 代码:view.setVisibility (View.VISIBLE);

 

不可见(invisible)

XML 文件:android:visibility="invisible"

Java 代码:view.setVisibility (View.INVISIBLE);

 

隐藏(GONE)

XML 文件:android:visibility="gone"

Java 代码:view.setVisibility (View.GONE);

 

 

为了区别三者,我建了一个 Dome 进行演示,先上 Dome 的代码,演示后就知道它们的区别:

XML 文件:

[html] view plaincopy

  1. <?xml version="1.0" encoding="utf-8"?>  

  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  

  3.     android:layout_width="fill_parent"  

  4.     android:layout_height="fill_parent"  

  5.     android:orientation="vertical">  

  6.     <LinearLayout  

  7.         android:layout_width="fill_parent"  

  8.         android:layout_height="wrap_content"  

  9.         android:orientation="horizontal"  

  10.         android:layout_marginBottom="20dip" >  

  11.   

  12.         <TextView  

  13.             android:layout_width="wrap_content"  

  14.             android:layout_height="wrap_content"  

  15.             android:layout_weight="1"  

  16.             android:background="#F00"  

  17.             android:text="TextView1"  

  18.             android:textSize="23sp"  

  19.             android:visibility="visible" />  

  20.   

  21.         <TextView  

  22.             android:id="@+id/mainTV2"  

  23.             android:layout_width="wrap_content"  

  24.             android:layout_height="wrap_content"  

  25.             android:layout_weight="1"  

  26.             android:background="#00F"  

  27.             android:text="TextView2"  

  28.             android:textSize="23sp"  

  29.             android:visibility="visible" />  

  30.     </LinearLayout>  

  31.       

  32.     <Button   

  33.         android:id="@+id/mainBtn1"  

  34.         android:layout_width="fill_parent"  

  35.         android:layout_height="wrap_content"  

  36.         android:text="TextView2 为 VISIBLE"  

  37.         android:onClick="mianOnClickListener"/>  

  38.       

  39.     <Button   

  40.         android:id="@+id/mainBtn2"  

  41.         android:layout_width="fill_parent"  

  42.         android:layout_height="wrap_content"  

  43.         android:text="TextView2 为 INVISIBLE"  

  44.         android:onClick="mianOnClickListener"/>  

  45.       

  46.     <Button   

  47.         android:id="@+id/mainBtn3"  

  48.         android:layout_width="fill_parent"  

  49.         android:layout_height="wrap_content"  

  50.         android:text="TextView2 为 GONE"  

  51.         android:onClick="mianOnClickListener"/>  

  52. </LinearLayout>  


后面三个 Button 只要是控制 TextView 的 visibility 的属性

Java 代码:

[java] view plaincopy

  1. package com.chindroid.visibility;  

  2.   

  3. import android.app.Activity;  

  4. import android.os.Bundle;  

  5. import android.view.View;  

  6. import android.widget.TextView;  

  7.   

  8. public class MainActivity extends Activity {  

  9.     /** TextView2 */  

  10.     private TextView mainTV2 = null;  

  11.       

  12.     @Override  

  13.     public void onCreate(Bundle savedInstanceState) {  

  14.         super.onCreate(savedInstanceState);  

  15.         setContentView(R.layout.main);  

  16.           

  17.         // 初始化数据  

  18.         initData();  

  19.     }  

  20.   

  21.     /** 初始化控件的方法 */  

  22.     private void initData() {  

  23.         mainTV2 = (TextView)findViewById(R.id.mainTV2);  

  24.     }  

  25.       

  26.     /** 

  27.      * MainActivity 中响应按钮点击事件的方法 

  28.      *  

  29.      * @param v 

  30.      */  

  31.     public void mianOnClickListener(View v){  

  32.         switch (v.getId()){  

  33.             case R.id.mainBtn1:{    // 按钮 1 的响应事件  

  34.                 // 设置 TextView2 可见  

  35.                 mainTV2.setVisibility(View.VISIBLE);  

  36.                 break;  

  37.             }  

  38.             case R.id.mainBtn2:{    // 按钮 2 的响应事件  

  39.                 // 设置 TextView2 不可见  

  40.                 mainTV2.setVisibility(View.INVISIBLE);  

  41.                 break;  

  42.             }  

  43.             case R.id.mainBtn3:{    // 按钮 3 的响应事件  

  44.                 // 设置 TextView2 隐藏  

  45.                 mainTV2.setVisibility(View.GONE);  

  46.                 break;  

  47.             }  

  48.             default:  

  49.                 break;  

  50.         }  

  51.     }  

  52. }  


由于程序一启动两个 TextView 都是可见的

当我们点击第 1 个按钮,把 TextView2visibility 属性设置为 INVISIBLE 时,程序如下如下图所示:

当我们点击第 3 个按钮,把 TextView2visibility 属性设置为 GONE 时,程序如下如下图所示:

当我们再点击第 1 个按钮,把 TextView2visibility 属性设置为 VISIBLE 时,TextView2 又呈现出来了,如下图所示:

 

由上面的演示可知

VISIBLE:设置控件可见

INVISIBLE:设置控件不可见

GONE:设置控件隐藏

 

而 INVISIBLE 和 GONE 的主要区别是:当控件 visibility 属性为 INVISIBLE 时,界面保留了 view 控件所占有的空间;而控件属性为 GONE 时,界面则不保留 view 控件所占有的空间。


关于delphi – 我得到RTTIMethod.Visibility = mvPublic用于私有记录方法. – 虫子?虫字旁的字的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于add a private constructor to hide the implicit public one(Utility classes should not have public ...、android – setVisibility()什么时候不在视图中触发onVisibilityChanged()?、android – View.setVisibility(View.VISIBLE)是否强制视图重绘,即使它已经可见?、Android 中 visibility 属性 VISIBLE、INVISIBLE、GONE 的区别的相关知识,请在本站寻找。

本文标签: