Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / ARC и .AddObject() / 25 сообщений из 28, страница 1 из 2
16.01.2015, 09:26:21
    #38855799
Cobalt747
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
Код: pascal
1.
cbxLogin.Items.AddObject(Users.FieldByName('NAME').AsString, TObject(ID));


даёт AV.
Может есть какие опробованные решения?
...
Рейтинг: 0 / 0
16.01.2015, 09:33:45
    #38855807
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
Cobalt747, если ID не объект, то так делать нельзя.
...
Рейтинг: 0 / 0
16.01.2015, 09:41:03
    #38855814
_user89
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
Cobalt747,

если нужно добавить строку, то попробуйте такой вариант
http://www.programmersforum.ru/showthread.php?t=47112#4
...
Рейтинг: 0 / 0
16.01.2015, 10:28:53
    #38855856
crause
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
Если правильно понял проблему по ссылке.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
type
  TString = class (TObject)
  private
    fValue: string;
    function GetValue: String;
    procedure SetValue(const Value: String);
  public
    constructor Create(AValue: String);
    property Value: String read GetValue write SetValue;
  end;

.......

constructor TString.Create(AValue: String);
begin
  inherited Create();
  fValue := AValue;
end;

function TString.GetValue: String;
begin
  if Self <> nil then
    Result := fValue
  else
    Result := 'string object is not created';
end;

procedure TString.SetValue(const Value: String);
begin
  if Self <> nil then
    if Value <> fValue then
      fValue := Value;
end;


вроде это был конечный вариант. точно глянуть не могу так как рабочий модуль пока не под рукой.
...
Рейтинг: 0 / 0
16.01.2015, 11:30:34
    #38855937
Cobalt747
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
crause,

то есть решения "изкаробки" не нашёл?
...
Рейтинг: 0 / 0
16.01.2015, 11:38:59
    #38855953
crause
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
У меня не особо много познаний тех вещей которые "из каробки".
Плохие познания в указателях и еще во многих вещах, и поэтому пришлось придумать такое.

Да и дальнейшую работу этот объект мне очень хорошо облегчил.
...
Рейтинг: 0 / 0
16.01.2015, 12:01:22
    #38855990
Граур Станислав
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
crauseЕсли правильно понял проблему по ссылке.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
type
  TString = class (TObject)
  private
    fValue: string;
    function GetValue: String;
    procedure SetValue(const Value: String);
  public
    constructor Create(AValue: String);
    property Value: String read GetValue write SetValue;
  end;

function TString.GetValue: String;
begin
  if Self <> nil then
    Result := fValue
  else
    Result := 'string object is not created';
end;




А зачем проверка на
Код: pascal
1.
Self <> nil

?
...
Рейтинг: 0 / 0
16.01.2015, 12:14:01
    #38856014
defecator
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
Kazantsev AlexeyCobalt747, если ID не объект, то так делать нельзя.

Это да.

Надо просто написать:
Код: pascal
1.
cbxLogin.Items.AddObject(Users.FieldByName('NAME').AsString, Pointer(ID));
...
Рейтинг: 0 / 0
16.01.2015, 12:18:16
    #38856021
stanilar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
Cobalt747Может есть какие опробованные решения?

Общее опробованное решение - написать наследника от класса cbxLogin, в котором определить наследника класса Items с нужным функционалом.

Увы, не все VCL решения обладают виртуальной функцией GetItemsClass, как ComboBox например.
...
Рейтинг: 0 / 0
16.01.2015, 12:43:20
    #38856054
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
defecatorНадо просто написать:
Код: pascal
1.
cbxLogin.Items.AddObject(Users.FieldByName('NAME').AsString, Pointer(ID));


Если Items это TStringList то и так писать тоже нельзя.
...
Рейтинг: 0 / 0
16.01.2015, 12:46:31
    #38856059
GunSmoker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
defecatorЭто да.

Надо просто написать:
Код: pascal
1.
cbxLogin.Items.AddObject(Users.FieldByName('NAME').AsString, Pointer(ID));



Проблема будет при очистке/модификации/чтении списка, когда список попытается уменьшить/увеличить ссылку у "объекта".
...
Рейтинг: 0 / 0
16.01.2015, 13:05:04
    #38856082
Dimonka
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
Cobalt747
Код: pascal
1.
cbxLogin.Items.AddObject(Users.FieldByName('NAME').AsString, TObject(ID));


даёт AV.
Может есть какие опробованные решения?
Как насчёт того, чтобы воспользоваться "нормальным" способом хранения зависимостей типа TDictionary<>?
...
Рейтинг: 0 / 0
16.01.2015, 13:17:46
    #38856092
defecator
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
GunSmokerdefecatorЭто да.

Надо просто написать:
Код: pascal
1.
cbxLogin.Items.AddObject(Users.FieldByName('NAME').AsString, Pointer(ID));



Проблема будет при очистке/модификации/чтении списка, когда список попытается уменьшить/увеличить ссылку у "объекта".

Сто лет уж таким способом пользуюсь, проблем вообще ни разу не замечал уже за очень много лет.
...
Рейтинг: 0 / 0
16.01.2015, 13:20:21
    #38856094
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
defecatorСто лет уж таким способом пользуюсь, проблем вообще ни разу не замечал уже за очень много лет.
Сто лет ты им пользуешься без ARC.
...
Рейтинг: 0 / 0
16.01.2015, 13:26:34
    #38856102
defecator
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
Kazantsev AlexeydefecatorСто лет уж таким способом пользуюсь, проблем вообще ни разу не замечал уже за очень много лет.
Сто лет ты им пользуешься без ARC.

Точняк ! Если не пользовался до сих пор с ARC, то и не нужен мне этот ARC))
...
Рейтинг: 0 / 0
16.01.2015, 13:35:40
    #38856117
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
defecatorТочняк ! Если не пользовался до сих пор с ARC, то и не нужен мне этот ARC))
В мобильном компиляторе выбора нет.
...
Рейтинг: 0 / 0
16.01.2015, 14:11:11
    #38856163
Cobalt747
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
DimonkaКак насчёт того, чтобы воспользоваться "нормальным" способом хранения зависимостей типа TDictionary<>?

прдлагаешь пихать запись сразу в TDictionary, а его потом в AddObject?
Типа сразу все поля, что ли?
...
Рейтинг: 0 / 0
16.01.2015, 15:33:58
    #38856292
stanilar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
У меня нет компилятора с ARC, но думаю что если выделить достаточный объем памяти под переменную, то счетчик ARC обломается.


Типа так:

Код: pascal
1.
2.
3.
4.
5.
  var P : pointer;
  begin
    P := new(65536); 
    Pinteger(P)^ := ID;    
    cbxLogin.Items.AddObject(Users.FieldByName('NAME').AsString, P);
...
Рейтинг: 0 / 0
16.01.2015, 15:44:50
    #38856305
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
stanilarУ меня нет компилятора с ARC, но думаю что если выделить достаточный объем памяти под переменную, то счетчик ARC обломается.
На вызове __ObjAddRef он обломается, в смысле AV получишь т.к. метод виртуальный и компилятору нужна ссылка на VMT класса для его вызова, а у тебя вместо ссылки на VMT будет записан хлам.

Я не пойму, чего так страдать-то? Универсальная объектная обертка пишется за пять минут.
...
Рейтинг: 0 / 0
16.01.2015, 15:53:15
    #38856319
GunSmoker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
Обходной путь:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
type
{$IFDEF AUTOREFCOUNT}
  TContainerObject = class
  strict private
    FValue: Variant;
  protected
    constructor Create(const AValue: Variant);
  public
    property Value: Variant read FValue;
  end;

constructor TContainerObject.Create(const AValue: Variant);
begin
  inherited Create;
  FValue := AValue;
end;

function FakeObject(const AValue: Variant): TObject;
begin
  Result := TContainerObject.Create(AValue);
end;

function RealObject(const AObject: TObject): Variant;
begin
  Result := (AObject as TContainerObject).Value;
end;
{$ELSE}
  FakeObject = TObject;
  RealObject = Cardinal;
{$ENDIF}



Код: pascal
1.
2.
  List.AddObject('Some value', FakeObject(ID));
  ID := RealObject(List.Objects[0]);
...
Рейтинг: 0 / 0
16.01.2015, 16:27:59
    #38856376
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
С дженериками:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
Type

 TWrapper<T> = Class

  Strict Private

   FValue    : T;
   FTypeInfo : PTypeInfo;

   {$REGION ' Accessors '}

    Procedure SetValue(Const AValue : T);
    Function GetValue : T;

   {$ENDREGION}

  Public

   Constructor Create(Const AValue : T);

   Class Operator Implicit(Const AValue : T) : TWrapper<T>;
   Class Operator Implicit(Const AWrapper : TWrapper<T>) : T;

   Property Value : T Read GetValue Write SetValue;

 End;

{ TWrapper<T> }

//
Procedure TWrapper<T>.SetValue(Const AValue : T);
Begin

 FValue    := AValue;
 FTypeInfo := TypeInfo(T);

End;
//

//
Function TWrapper<T>.GetValue : T;
Begin

 If TypeInfo(T) <> FTypeInfo Then
  Raise Exception.CreateFmt('Invalid type casting. Expected: %s, actual: %s', [PTypeInfo(TypeInfo(T)).NameFld.ToString, FTypeInfo.NameFld.ToString]);

 Result := FValue;

End;
//

//
Constructor TWrapper<T>.Create(Const AValue : T);
Begin

 Inherited Create;

 Value := AValue;

End;
//

//
Class Operator TWrapper<T>.Implicit(Const AValue : T) : TWrapper<T>;
Begin

 Result := TWrapper<T>.Create(AValue);

End;
//

//
Class Operator TWrapper<T>.Implicit(Const AWrapper : TWrapper<T>) : T;
Begin

 Result := AWrapper.Value;

End;
//


Использование:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Var

 List : TStringList;
 ID   : Integer;

begin

 List := TStringList.Create;
 ID   := 1024;

 List.AddObject('name', TWrapper<Integer>(ID));
 ID := TWrapper<Integer>(List.Objects[0]);

end.


p.s. Работоспособность не проверял.
...
Рейтинг: 0 / 0
16.01.2015, 16:44:44
    #38856391
defecator
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
Kazantsev AlexeyС дженериками:

а слабо без дженериков ?
...
Рейтинг: 0 / 0
16.01.2015, 16:49:37
    #38856397
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
defecatorа слабо без дженериков ?
Не слабо даже без объектов
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
26.07.2017, 21:38:14
    #39495595
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
Решение с поддержкой кеширования значений (для обеспечения работы IndexOfObject):
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

Uses

 System.SysUtils, Generics.Collections, System.TypInfo, System.Classes;

Type

 TWrapper<T> = Class

  Strict Private

   Class Var

    FCache : TDictionary<T, TObject>;

   Class Constructor Initialize;
   Class Destructor Finalize;

  Strict Private

   FValue    : T;
   FTypeInfo : PTypeInfo;

   {$REGION ' Accessors '}

    Procedure SetValue(Const AValue : T);
    Function GetValue : T;

   {$ENDREGION}

  Public

   Constructor Create(Const AValue : T);

   Class Operator Implicit(Const AValue : T) : TWrapper<T>;
   Class Operator Implicit(Const AWrapper : TWrapper<T>) : T;

   Function __ObjRelease : Integer; Override;

   Property Value : T Read GetValue Write SetValue;

 End;

{ TWrapper<T> }

//
Class Constructor TWrapper<T>.Initialize;
Begin

 FCache := TDictionary<T, TObject>.Create;

End;
//

//
Class Destructor TWrapper<T>.Finalize;
Begin

 FCache.Free;

End;
//

//
Procedure TWrapper<T>.SetValue(Const AValue : T);
Begin

 FValue    := AValue;
 FTypeInfo := TypeInfo(T);

End;
//

//
Function TWrapper<T>.GetValue : T;
Begin

 If TypeInfo(T) <> FTypeInfo Then
  Raise Exception.CreateFmt('Invalid type casting. Expected: %s, actual: %s', [PTypeInfo(TypeInfo(T)).NameFld.ToString, FTypeInfo.NameFld.ToString]);

 Result := FValue;

End;
//

//
Constructor TWrapper<T>.Create(Const AValue : T);
Begin

 Inherited Create;

 Value := AValue;

End;
//

//
Class Operator TWrapper<T>.Implicit(Const AValue : T) : TWrapper<T>;
Begin

 TMonitor.Enter(FCache);
 Try

  If Not FCache.TryGetValue(AValue, TObject(Result)) Then
   Begin

    Result := TWrapper<T>.Create(AValue);

    FCache.Add(AValue, Result);

   End;

 Finally

  TMonitor.Exit(FCache);

 End;

End;
//

//
Class Operator TWrapper<T>.Implicit(Const AWrapper : TWrapper<T>) : T;
Begin

 Result := AWrapper.Value;

End;
//

//
Function TWrapper<T>.__ObjRelease : Integer;
Begin

 Result := Inherited __ObjRelease;

 If Result = 1 Then
  Begin

   TMonitor.Enter(FCache);
   Try

    FCache.Remove(FValue);

   Finally

    TMonitor.Exit(FCache);

   End;

  End;

End;
//

Var

 [weak]
 w  : TWrapper<Integer>; // for test of releasing

Procedure Test;
Var

 sl : TStringList;
 index : Integer;

Begin

 sl := TStringList.Create;

 w := TWrapper<Integer>(1);
 WriteLn('addr of w: ', NativeUInt(Pointer(w)));

 sl.AddObject('one', w);
 sl.AddObject('two', TWrapper<Integer>(2));
 sl.AddObject('three', TWrapper<Integer>(3));
 sl.AddObject('four', TWrapper<Integer>(4));
 sl.AddObject('five', TWrapper<Integer>(1));

 For Index := 0 To sl.Count - 1 Do
  WriteLn(sl[Index], ' = ', TWrapper<Integer>(sl.Objects[Index]).Value, ' (', NativeUInt(Pointer(sl.Objects[Index])), ')');

End;

Begin

 Test;

 WriteLn('addr of w: ', NativeUInt(Pointer(w)));

End.


Результат:
Код: sql
1.
2.
3.
4.
5.
6.
7.
addr of w: 24513104
one = 1 (24513104)
two = 2 (24512944)
three = 3 (24512784)
four = 4 (24509344)
five = 1 (24513104)
addr of w: 0
...
Рейтинг: 0 / 0
27.07.2017, 08:27:51
    #39495711
krapotkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ARC и .AddObject()
а вариант использовать экранные объекты только для отображения, а данные хранить не на экране, а в модели данных вообще не рассматривается?
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / ARC и .AddObject() / 25 сообщений из 28, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]