描述
在開發(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
可以看到,普通方法和類的構(gòu)造方法傳參為對象時汹族,傳參只是產(chǎn)生對象的引用萧求,將對象的引用置為null,并不會影響把原對象置null顶瞒,這里個人覺得跟對象引用計(jì)數(shù)有關(guān),將對象引用置null夸政,只是將對象引用計(jì)數(shù)減1,只有引用計(jì)數(shù)為0時搁拙,對象才會被回收秒梳;
2法绵、將對象引用重新實(shí)例化或賦值其它對象引用
可以看到,對象引用的重新實(shí)例化或賦值其它對象引用酪碘,對原對象沒有影響朋譬;
3、對象引用里的成員變量值改變
可以看到兴垦,對象引用里的成員變量值改變徙赢,所有對象的引用都會變化
結(jié)論
個人理解,不對請多多指教
-
對象實(shí)例化時,實(shí)際是在內(nèi)存空間創(chuàng)建屬于自己的一片空間探越,類似創(chuàng)建了房子A狡赐;
-
將實(shí)例化的對象A賦值給A1對象或者再將A1對象賦值給A2對象,其實(shí)A1對象和A2對象都是這個實(shí)例化A對象的引用钦幔,也就是A1和A2都指向A的內(nèi)存空間枕屉,類似A1和A2都有A房子的鑰匙,可以進(jìn)入A房子為所欲為鲤氢;
- 對引用對象的成員變量改變時搀擂,所有對象的引用都會變化,類似A1進(jìn)入A房子卷玉,換了墻的顏色哨颂,其他人進(jìn)來A房子會看到變化;
-
將對象的引用置null或指向其它的對象相种,也就是讓A1或A2不指向A的內(nèi)存空間威恼,對A所在的內(nèi)存空間沒有影響,類似于A1或A2將手里的鑰匙換成其它房子的了寝并,所以A1和A2以后再也和房子A無關(guān)了箫措;
- 普通方法或類的構(gòu)造方法的傳參為對象時,傳參實(shí)際是對對象的引用食茎,將對象引用置null并不會影響原對象蒂破;