關(guān)于flutter對象引用的理解

描述

在開發(fā)中向臀,不可避免會將對象傳遞給其它對象使用运杭,其它對象對傳遞來的對象的操作會引起原對象什么變化呢蛹头?

示例

示例有兩個頁面院塞,一個頁面展示原對象的變化遮晚,另一個頁面展示對原對象引用操作對原對象的影響
原對象變化頁:

import 'package:flutter/material.dart';

import 'test_model_cite_page.dart';

class ModelCitePage extends StatefulWidget {
  const ModelCitePage();

  @override
  _ModelCitePageState createState() => _ModelCitePageState();
}

class _ModelCitePageState extends State<ModelCitePage> {
  _ModelCitePageState();

  CiteModel _testCiteModel;

  @override
  void initState() {
    super.initState();
    _testCiteModel = CiteModel(1);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('對象引用計(jì)數(shù)'),
      ),
      body: Container(
        width: double.infinity,
        height: double.infinity,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Text(
              '原對象:${_testCiteModel ?? ''}',
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 20,
            ),
            RaisedButton(
              child: Text("對象引用計(jì)數(shù)操作"),
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) {
                    return TestModelCitePage(_testCiteModel);
                  }),
                );
              },
            ),
          ],
        ),
      ),
    );
  }

  @override
  void deactivate() {
    super.deactivate();
    print('ModelCitePage deactivate  ${_testCiteModel ?? 'null'}');
  }

  @override
  void dispose() {
    super.dispose();
  }
}

對原對象引用操作頁:

import 'package:flutter/material.dart';

class TestModelCitePage extends StatefulWidget {
  final CiteModel _testCiteModel;

  const TestModelCitePage(this._testCiteModel);

  @override
  _TestModelCitePageState createState() =>
      _TestModelCitePageState(this._testCiteModel);
}

class _TestModelCitePageState extends State<TestModelCitePage> {
  CiteModel _testCiteModel;
  CiteModel _tmpTestCiteModel;
  String operateText;
  String showInfo;
  String hintText;

  _TestModelCitePageState(this._testCiteModel);

  @override
  void initState() {
    super.initState();
    print('test cite model page   ${_testCiteModel ?? 'null'}');
    _tmpTestCiteModel = _testCiteModel;
    _updateView('_tmpTestCiteModel = _testCiteModel',
        '外部傳進(jìn)來的_testCiteModel賦值給_tmpTestCiteModel');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('測試引用'),
      ),
      body: SingleChildScrollView(
        child: Container(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Text(
                '操作:${operateText ?? ''}',
                textAlign: TextAlign.center,
                style: TextStyle(color: Colors.green),
              ),
              SizedBox(
                height: 10,
              ),
              Text(
                showInfo ?? '',
                textAlign: TextAlign.center,
              ),
              SizedBox(
                height: 10,
              ),
              Text(
                '提示:${hintText ?? ''}',
                textAlign: TextAlign.center,
                style: TextStyle(color: Colors.redAccent),
              ),
              SizedBox(
                height: 20,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  RaisedButton(
                    child: Text("方法置空原對象"),
                    onPressed: () {
                      _nullModel(_testCiteModel);
                      _updateView(
                          '_nullModel(_testCiteModel)', '只是置空原對象引用,對原對象引用沒影響');
                    },
                  ),
                  RaisedButton(
                    child: Text("方法置空引用對象"),
                    onPressed: () {
                      _nullModel(_tmpTestCiteModel);
                      _updateView('_nullModel(_tmpTestCiteModel)',
                          '只是置空原對象引用拦止,對原對象引用沒影響');
                    },
                  ),
                ],
              ),
              RaisedButton(
                child: Text("引用置為null"),
                onPressed: () {
                  _testCiteModel = null; //不會影響_tmpTestCiteModel和傳進(jìn)來值
                  print('test cite model page   ${_testCiteModel ?? 'null'}');
                  print(
                      'tmp test cite model page   ${_tmpTestCiteModel ?? 'null'}');
                  _updateView(
                      '_testCiteModel = null', '不會影響_tmpTestCiteModel和傳進(jìn)來值');
                },
              ),
              SizedBox(
                height: 20,
              ),
              RaisedButton(
                child: Text("賦值的引用置為null"),
                onPressed: () {
                  _tmpTestCiteModel = null; //不會影響_testCiteModel和傳進(jìn)來值
                  print('test cite model page   ${_testCiteModel ?? 'null'}');
                  _updateView(
                      '_tmpTestCiteModel = null', '不會影響_testCiteModel和傳進(jìn)來值');
                },
              ),
              SizedBox(
                height: 20,
              ),
              RaisedButton(
                child: Text("引用重新賦值"),
                onPressed: () {
                  _testCiteModel = CiteModel(2); //不會影響_tmpTestCiteModel和傳進(jìn)來值
                  print('test cite model page   ${_testCiteModel ?? 'null'}');
                  print(
                      'tmp test cite model page   ${_tmpTestCiteModel ?? 'null'}');
                  _updateView('_testCiteModel = CiteModel(2)',
                      '不會影響_tmpTestCiteModel和傳進(jìn)來值');
                },
              ),
              SizedBox(
                height: 20,
              ),
              RaisedButton(
                child: Text("賦值的引用重新賦值"),
                onPressed: () {
                  _tmpTestCiteModel = CiteModel(3); //不會影響_testCiteModel和傳進(jìn)來值
                  print('test cite model page   ${_testCiteModel ?? 'null'}');
                  _updateView('_tmpTestCiteModel = CiteModel(3)',
                      '不會影響_testCiteModel和傳進(jìn)來值');
                },
              ),
              SizedBox(
                height: 20,
              ),
              RaisedButton(
                child: Text("修改引用值"),
                onPressed: () {
                  _testCiteModel?.count = 4; //影響_testCiteModel和傳進(jìn)來值
                  print('test cite model page   ${_testCiteModel ?? 'null'}');
                  print(
                      'tmp test cite model page   ${_tmpTestCiteModel ?? 'null'}');
                  _updateView(
                      '_testCiteModel?.count = 4', '影響_testCiteModel和傳進(jìn)來值');
                },
              ),
              SizedBox(
                height: 20,
              ),
              RaisedButton(
                child: Text("修改賦值的引用值"),
                onPressed: () {
                  _tmpTestCiteModel?.count = 5; //影響_tmpTestCiteModel和傳進(jìn)來值
                  print('test cite model page   ${_testCiteModel ?? 'null'}');
                  _updateView('_tmpTestCiteModel.count = 5',
                      '影響_tmpTestCiteModel和傳進(jìn)來值');
                },
              ),
            ],
          ),
        ),
      ),
    );
  }

  @override
  void deactivate() {
    super.deactivate();
    print('test cite page deactivate');
  }

  @override
  void dispose() {
    super.dispose();
    print('test cite page dispose');
  }

  void _updateView(String operate, String hint) {
    setState(() {
      operateText = operate;
      showInfo = 'test cite model:   ${_testCiteModel ?? 'null'}\n' +
          'tmp test cite model:   ${_tmpTestCiteModel ?? 'null'}';
      hintText = hint;
    });
  }

  void _nullModel(CiteModel model) {
    model = null;
  }
}

class CiteModel {
  int count;

  CiteModel(this.count);

  @override
  String toString() {
    return 'TestCiteModel count is $count';
  }
}

操作:
1县遣、將對象引用置為null

效果.gif

可以看到,普通方法和類的構(gòu)造方法傳參為對象時汹族,傳參只是產(chǎn)生對象的引用萧求,將對象的引用置為null,并不會影響把原對象置null顶瞒,這里個人覺得跟對象引用計(jì)數(shù)有關(guān),將對象引用置null夸政,只是將對象引用計(jì)數(shù)減1,只有引用計(jì)數(shù)為0時搁拙,對象才會被回收秒梳;

2法绵、將對象引用重新實(shí)例化或賦值其它對象引用

效果.gif

可以看到,對象引用的重新實(shí)例化或賦值其它對象引用酪碘,對原對象沒有影響朋譬;

3、對象引用里的成員變量值改變

效果.gif

可以看到兴垦,對象引用里的成員變量值改變徙赢,所有對象的引用都會變化

結(jié)論

個人理解,不對請多多指教

  • 對象實(shí)例化時,實(shí)際是在內(nèi)存空間創(chuàng)建屬于自己的一片空間探越,類似創(chuàng)建了房子A狡赐;


    A實(shí)例化.png
  • 將實(shí)例化的對象A賦值給A1對象或者再將A1對象賦值給A2對象,其實(shí)A1對象和A2對象都是這個實(shí)例化A對象的引用钦幔,也就是A1和A2都指向A的內(nèi)存空間枕屉,類似A1和A2都有A房子的鑰匙,可以進(jìn)入A房子為所欲為鲤氢;


    對象引用.png
  • 對引用對象的成員變量改變時搀擂,所有對象的引用都會變化,類似A1進(jìn)入A房子卷玉,換了墻的顏色哨颂,其他人進(jìn)來A房子會看到變化;
  • 將對象的引用置null或指向其它的對象相种,也就是讓A1或A2不指向A的內(nèi)存空間威恼,對A所在的內(nèi)存空間沒有影響,類似于A1或A2將手里的鑰匙換成其它房子的了寝并,所以A1和A2以后再也和房子A無關(guān)了箫措;


    對象引用置null.png
  • 普通方法或類的構(gòu)造方法的傳參為對象時,傳參實(shí)際是對對象的引用食茎,將對象引用置null并不會影響原對象蒂破;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市别渔,隨后出現(xiàn)的幾起案子附迷,更是在濱河造成了極大的恐慌,老刑警劉巖哎媚,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件喇伯,死亡現(xiàn)場離奇詭異,居然都是意外死亡拨与,警方通過查閱死者的電腦和手機(jī)稻据,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人捻悯,你說我怎么就攤上這事匆赃。” “怎么了今缚?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵算柳,是天一觀的道長。 經(jīng)常有香客問我姓言,道長瞬项,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任何荚,我火速辦了婚禮囱淋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘餐塘。我一直安慰自己妥衣,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布戒傻。 她就那樣靜靜地躺著称鳞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪稠鼻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天狂票,我揣著相機(jī)與錄音候齿,去河邊找鬼。 笑死闺属,一個胖子當(dāng)著我的面吹牛慌盯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播掂器,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼亚皂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了国瓮?” 一聲冷哼從身側(cè)響起灭必,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎乃摹,沒想到半個月后禁漓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡孵睬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年播歼,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掰读。...
    茶點(diǎn)故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡秘狞,死狀恐怖叭莫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情烁试,我是刑警寧澤雇初,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站廓潜,受9級特大地震影響抵皱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜辩蛋,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一呻畸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧悼院,春花似錦伤为、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至颖医,卻和暖如春位衩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背熔萧。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工糖驴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人佛致。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓贮缕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親俺榆。 傳聞我的和親對象是個殘疾皇子感昼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容