美文网首页Flutter
关于flutter对象引用的理解

关于flutter对象引用的理解

作者: HawkFlying | 来源:发表于2020-11-24 17:16 被阅读0次

    描述

    在开发中,不可避免会将对象传递给其它对象使用,其它对象对传递来的对象的操作会引起原对象什么变化呢?

    示例

    示例有两个页面,一个页面展示原对象的变化,另一个页面展示对原对象引用操作对原对象的影响
    原对象变化页:

    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('对象引用计数'),
          ),
          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("对象引用计数操作"),
                  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',
            '外部传进来的_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和传进来值
                      print('test cite model page   ${_testCiteModel ?? 'null'}');
                      print(
                          'tmp test cite model page   ${_tmpTestCiteModel ?? 'null'}');
                      _updateView(
                          '_testCiteModel = null', '不会影响_tmpTestCiteModel和传进来值');
                    },
                  ),
                  SizedBox(
                    height: 20,
                  ),
                  RaisedButton(
                    child: Text("赋值的引用置为null"),
                    onPressed: () {
                      _tmpTestCiteModel = null; //不会影响_testCiteModel和传进来值
                      print('test cite model page   ${_testCiteModel ?? 'null'}');
                      _updateView(
                          '_tmpTestCiteModel = null', '不会影响_testCiteModel和传进来值');
                    },
                  ),
                  SizedBox(
                    height: 20,
                  ),
                  RaisedButton(
                    child: Text("引用重新赋值"),
                    onPressed: () {
                      _testCiteModel = CiteModel(2); //不会影响_tmpTestCiteModel和传进来值
                      print('test cite model page   ${_testCiteModel ?? 'null'}');
                      print(
                          'tmp test cite model page   ${_tmpTestCiteModel ?? 'null'}');
                      _updateView('_testCiteModel = CiteModel(2)',
                          '不会影响_tmpTestCiteModel和传进来值');
                    },
                  ),
                  SizedBox(
                    height: 20,
                  ),
                  RaisedButton(
                    child: Text("赋值的引用重新赋值"),
                    onPressed: () {
                      _tmpTestCiteModel = CiteModel(3); //不会影响_testCiteModel和传进来值
                      print('test cite model page   ${_testCiteModel ?? 'null'}');
                      _updateView('_tmpTestCiteModel = CiteModel(3)',
                          '不会影响_testCiteModel和传进来值');
                    },
                  ),
                  SizedBox(
                    height: 20,
                  ),
                  RaisedButton(
                    child: Text("修改引用值"),
                    onPressed: () {
                      _testCiteModel?.count = 4; //影响_testCiteModel和传进来值
                      print('test cite model page   ${_testCiteModel ?? 'null'}');
                      print(
                          'tmp test cite model page   ${_tmpTestCiteModel ?? 'null'}');
                      _updateView(
                          '_testCiteModel?.count = 4', '影响_testCiteModel和传进来值');
                    },
                  ),
                  SizedBox(
                    height: 20,
                  ),
                  RaisedButton(
                    child: Text("修改赋值的引用值"),
                    onPressed: () {
                      _tmpTestCiteModel?.count = 5; //影响_tmpTestCiteModel和传进来值
                      print('test cite model page   ${_testCiteModel ?? 'null'}');
                      _updateView('_tmpTestCiteModel.count = 5',
                          '影响_tmpTestCiteModel和传进来值');
                    },
                  ),
                ],
              ),
            ),
          ),
        );
      }
    
      @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
    可以看到,普通方法和类的构造方法传参为对象时,传参只是产生对象的引用,将对象的引用置为null,并不会影响把原对象置null,这里个人觉得跟对象引用计数有关,将对象引用置null,只是将对象引用计数减1,只有引用计数为0时,对象才会被回收;

    2、将对象引用重新实例化或赋值其它对象引用

    效果.gif
    可以看到,对象引用的重新实例化或赋值其它对象引用,对原对象没有影响;

    3、对象引用里的成员变量值改变

    效果.gif
    可以看到,对象引用里的成员变量值改变,所有对象的引用都会变化

    结论

    个人理解,不对请多多指教

    • 对象实例化时,实际是在内存空间创建属于自己的一片空间,类似创建了房子A;


      A实例化.png
    • 将实例化的对象A赋值给A1对象或者再将A1对象赋值给A2对象,其实A1对象和A2对象都是这个实例化A对象的引用,也就是A1和A2都指向A的内存空间,类似A1和A2都有A房子的钥匙,可以进入A房子为所欲为;


      对象引用.png
    • 对引用对象的成员变量改变时,所有对象的引用都会变化,类似A1进入A房子,换了墙的颜色,其他人进来A房子会看到变化;
    • 将对象的引用置null或指向其它的对象,也就是让A1或A2不指向A的内存空间,对A所在的内存空间没有影响,类似于A1或A2将手里的钥匙换成其它房子的了,所以A1和A2以后再也和房子A无关了;


      对象引用置null.png
    • 普通方法或类的构造方法的传参为对象时,传参实际是对对象的引用,将对象引用置null并不会影响原对象;

    相关文章

      网友评论

        本文标题:关于flutter对象引用的理解

        本文链接:https://www.haomeiwen.com/subject/hyiiiktx.html