全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:711
推到 Plurk!
推到 Facebook!

Object的Create和Free以及ARC

 
pcplayer99
尊榮會員


發表:142
回覆:740
積分:591
註冊:2003-01-21

發送簡訊給我
#1 引用回覆 回覆 發表時間:2016-04-01 10:27:23 IP:120.237.xxx.xxx 訂閱
在Windows底下习惯了的Object的生命周期管理,在Android和iOS底下不一样了。因为不一样,不注意的话,按照以前的经验来Codeing,会有潜在的问题。比如,我需要几个Object来记录当前的人。比如TPerson。放进一个TObjectList里面,叫它PersonList。而且这个PersonList.OwnsObjects=True;So,有三个人,我就Create三个TPerson的Object,放进PersonList里面。当我用完以后,PersonList.Clear就会将里面的ObjectPersonfree掉。下次再需要2个,就再来重复两次:Person:=TPerson.Create;PersonList.Add(Person)。在Windows里面,上述做法正确。在Android和iOS里面,别以为你第二次做的TPerson.Create会是新的。它很可能是旧的,是之前你以为Free掉了的!
tick228
中階會員


發表:1
回覆:28
積分:55
註冊:2003-11-03

發送簡訊給我
#2 引用回覆 回覆 發表時間:2016-04-01 15:13:36 IP:180.205.xxx.xxx 未訂閱
雖然你沒說明, 遇到的問題是什麼, 不過, 我猜想, 是不是發生變數初始值, 不是預想值的問題.

如果是這個問題, 那你可能要加強一下 Coding 觀念 - "只要是我要用的變數, 就由我來指定初始值"

變數初始值在 Create 時, 是不確定值, 會不會清 0, 不一定, 這跟作業系統的記憶體使用方式及呼叫那個 malloc 函數有關,
即然是不確定值, 那你怎放心直接拿來使用, 所以, 最好的方式, 是在 Create 時, 自己來設定初始值(就算是 0 也要設定).

若是有做上面的動作, 那就不管 TPerson.Create 時, OS 給你的記憶體是新的, 或是舊的回收, 都不會有你所說的潛在問題發生.

taishyang
站務副站長


發表:377
回覆:5486
積分:4552
註冊:2002-10-08

發送簡訊給我
#3 引用回覆 回覆 發表時間:2016-04-01 15:32:01 IP:59.127.xxx.xxx 訂閱
看起來應該不是初始值的問題,而是釋放記憶體(delete/free)後的問題
五星會員的題目不會那麼單純的啦:P



===================引 用 tick228 文 章=================== 雖然你沒說明, 遇到的問題是什麼, 不過, 我猜想, 是不是發生變數初始值, 不是預想值的問題.

如果是這個問題, 那你可能要加強一下 Coding 觀念 - "只要是我要用的變數, 就由我來指定初始值"

變數初始值在 Create 時, 是不確定值, 會不會清 0, 不一定, 這跟作業系統的記憶體使用方式及呼叫那個 malloc 函數有關,
即然是不確定值, 那你怎放心直接拿來使用, 所以, 最好的方式, 是在 Create 時, 自己來設定初始值(就算是 0 也要設定).

若是有做上面的動作, 那就不管 TPerson.Create 時, OS 給你的記憶體是新的, 或是舊的回收, 都不會有你所說的潛在問題發生.

編輯記錄
taishyang 重新編輯於 2016-04-01 15:33:04, 註解 無‧
tick228
中階會員


發表:1
回覆:28
積分:55
註冊:2003-11-03

發送簡訊給我
#4 引用回覆 回覆 發表時間:2016-04-01 22:48:01 IP:180.206.xxx.xxx 未訂閱
哈哈, 因為從內文看不出問題是什麼, 所以也只能猜測大概是記憶體配置/釋放的關係.

這其實也只是因為在 Windows 和 Android(Java) 對記憶體的配置/釋放方式不一樣(IOS 不熟, 所以不清楚) 而已,
但是這並不影響 APP 對記憶體的使用.

所以也只能等待樓主是否能將問題詳述, 才能了解.

===================引 用 taishyang 文 章===================
看起來應該不是初始值的問題,而是釋放記憶體(delete/free)後的問題
五星會員的題目不會那麼單純的啦:P

編輯記錄
tick228 重新編輯於 2016-04-01 23:08:33, 註解 無‧
leveon
資深會員


發表:30
回覆:386
積分:303
註冊:2012-02-12

發送簡訊給我
#5 引用回覆 回覆 發表時間:2016-04-02 00:18:39 IP:60.249.xxx.xxx 訂閱
原文指的應該是這個
http://stackoverflow.com/questions/6518012/why-does-tobjectlistt-clear-not-free-objects

聽樓主描述 可能就是Notify機制在android不作用 如果是這樣 這應該是個bug




===================引 用 tick228 文 章===================
哈哈, 因為從內文看不出問題是什麼, 所以也只能猜測大概是記憶體配置/釋放的關係.

這其實也只是因為在 Windows 和 Android(Java) 對記憶體的配置/釋放方式不一樣(IOS 不熟, 所以不清楚) 而已,
但是這並不影響 APP 對記憶體的使用.

所以也只能等待樓主是否能將問題詳述, 才能了解.

===================引 用 taishyang 文 章===================
看起來應該不是初始值的問題,而是釋放記憶體(delete/free)後的問題
五星會員的題目不會那麼單純的啦:P

tick228
中階會員


發表:1
回覆:28
積分:55
註冊:2003-11-03

發送簡訊給我
#6 引用回覆 回覆 發表時間:2016-04-02 06:17:50 IP:180.206.xxx.xxx 未訂閱
抱歉, 是我誤會了, 沒注意到樓主標題的 "ARC" (Automatic Reference Counting),
我都是用 2010 版在開發 PC AP, 不知道現在版本有對 Mobile APP 提供這新的功能, 以致回出錯誤的文,
讓各位見笑了, 也向樓主道歉~

經查 docwiki.embarcadero.com 及查看網路相關問題, TObjectList.Notify() 並未針對 lnDeleted 做 TObject(Ptr).__ObjRelease 的動作,
所以, TObjectList.Clear; 確實不會清除記憶體, 會造成 Memory leaks 的現象, 看來的確像是 Bug, 但也疑惑這問題應從最早支援 Mobile APP 的版本就存在, 何以至今 Embarcadero 還不願解決.

看來, 若要讓 Clear 正常運作, 也只能自行繼承 TObjectList.Notify() 自行 Free , 如下
procedure TMyObjectList.Notify(Ptr: Pointer; Action: TListNotification);
begin
{$IFDEF AUTOREFCOUNT}
if (Action = lnDeleted) and OwnsObjects then
TObject(Ptr).DisposeOf;
{$ENDIF !AUTOREFCOUNT}
inherited Notify(Ptr, Action);
end;
或許可解決這個問題.

===================引 用 leveon 文 章===================
原文指的應該是這個
http://stackoverflow.com/questions/6518012/why-does-tobjectlistt-clear-not-free-objects

聽樓主描述 可能就是Notify機制在android不作用 如果是這樣 這應該是個bug
編輯記錄
tick228 重新編輯於 2016-04-02 06:34:28, 註解 無‧
pcplayer99
尊榮會員


發表:142
回覆:740
積分:591
註冊:2003-01-21

發送簡訊給我
#7 引用回覆 回覆 發表時間:2016-04-04 23:58:47 IP:36.36.xxx.xxx 訂閱
我的问题,更复杂些。

还是假设它是一个我自己定义的 TPerson

对应每个 Person,有个外部的 Interface,当 Person 有动作时,调用这个 Interface 通知外面。假设它是 IMyNotifyIntf

Person.MyNotifyIntf := XXX as IMyNotifyIntf.

这里很奇怪的是,第二次 Create 出来的心得 Persong, 做 Person.MyNotifyIntf := XXX as IMyNotifyIntf; 操作的时候,会 AV,结果是直接导致 APP 崩溃闪退。

但,如果我不是简单的 MyObjectList.Clear,而是跑个 for 回圈,逐个把里面的 Person 拿出来,做:Person.MyNotifyIntf := nil;Person.Free;则不会有问题了。

但上述直接 MyObjectList.Clear 的做法,在 Windows 底下,是没有问题的。所以我才怀疑是 Android 底下,Person 并没有真正 Free 掉导致的。
系統時間:2017-12-17 12:19:08
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!