我无法在调试模型中重现错误。但在发布的应用程序中,使用react-navigation
多次返回和导航选项卡后,该应用程序崩溃。我通过sentry
得到了错误。
应用程序崩溃是因为线程太多吗?每次浏览选项卡时,都会有4个http请求。
感谢您的选择。以下是错误:
OS Version: iOS 12.1 (16B92)
Report Version: 104
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Crashed Thread: 22
Application Specific Information:
*** CFRelease() called with NULL *** > countByEnumeratingWithState:objects:count: > objectAtIndexedSubscript:
Thread 22 Crashed:
0 CoreFoundation 0x311d5df20 CFRelease
1 INKubatorApp 0x202f00d48 _ZN5folly6detail15str_to_integralIxEENS_8ExpectedIT_NS_14ConversionCodeEEEPNS_5RangeIPKcEE
2 CoreFoundation 0x311e7f600 <redacted>
3 CoreFoundation 0x311d5d530 <redacted>
4 CoreFoundation 0x311d5e114 <redacted>
5 INKubatorApp 0x202e64a24 <redacted>
6 INKubatorApp 0x202eab7c8 RCTFBQuickPerformanceLoggerConfigureHooks
7 INKubatorApp 0x202eab524 RCTFBQuickPerformanceLoggerConfigureHooks
8 libdispatch.dylib 0x3113a66c8 <redacted>
9 libdispatch.dylib 0x3113a7484 <redacted>
10 libdispatch.dylib 0x311381fb0 <redacted>
11 libdispatch.dylib 0x311382af4 <redacted>
12 libdispatch.dylib 0x31138af14 <redacted>
13 libsystem_pthread.dylib 0x3117c00dc _pthread_wqthread
我的导航代码:
<TouchableOpacity onPress={ () => this.props.navigation.navigate('BillList',{ listType: 'investment' }) }>
BillList.js
:
render(){
return (
<View style={ styles.container }>
<HeaderCom title={ this.getListTitle() } backgEvent={ () => this.props.navigation.goBack() }/>
<InvestmentTab screenProps={ this.props.screenProps } />
</View>
)
}
InvestmentTab.js
:
const InvestmentTab = createMaterialTopTabNavigator({
allBills: {
screen: BillContent,
navigationOptions: {
tabBarLabel: I18n.t('investment.all'),
}
},
toBePaidBills: {
screen: BillContent,
navigationOptions: {
tabBarLabel: I18n.t('investment.to_be_paid')
}
},
paidBills: {
screen: BillContent,
navigationOptions: {
tabBarLabel: I18n.t('investment.paid')
}
},
closedBills: {
screen: BillContent,
navigationOptions: {
tabBarLabel: I18n.t('investment.closed')
}
},
}, {
animationEnabled: true,
tabBarPosition: 'top', // 修改导航的位置
swipeEnabled: true,
tabBarOptions: {
activeTintColor: commonStyle.main, // 选中的颜色
inactiveTintColor: commonStyle.bill_tab_inactive,
showIcon: false, // 是否显示小图标
style: { // 可以设置tab的各种样式
backgroundColor: commonStyle.white, //底部tab的背景颜色
height: 56,
borderBottomWidth: 1,
borderBottomColor: commonStyle.border_color,
borderTopWidth: 1,
borderTopColor: commonStyle.border_color,
elevation: 0,
justifyContent: 'space-between'
},
labelStyle: {
fontSize: 14,
textAlignVertical: 'center',
paddingTop: 3,
marginHorizontal: -1,
},
indicatorStyle: {
backgroundColor: commonStyle.main,
width: Dimensions.get('window').width * .16,
position: 'absolute',
left: '4.5%',
},
pressOpacity: 0.8,
}
});
export default InvestmentTab;
BillContent.js
只是一个FlatList,我在componentWillMount()
从服务器获取数据。
componentWillMount() {
appStorage.getUser().then(user => {
this.setState({ userId: user.user_id });
this._onRefresh();
this.props.navigation.addListener('willFocus', this._onRefresh);
});
}
在发布的应用程序中,在多次返回并导航一个选项卡(哪个名称是BillList,我很抱歉这个奇怪的名称(后,该应用程序崩溃了。
首先,我认为这是由于过多的http请求和对react-navigation
的不正确使用造成的。以下是我的修复代码:
我的导航代码:
<TouchableOpacity onPress={ () => this.props.navigation.navigate('MyTab',{ listType: 'investment' }) }>
MyTab.js
,是的,我让导航不嵌入名为BillList.js
:的组件中
export default createMaterialTopTabNavigator({
allBills: {
screen: MyList,
navigationOptions: {
tabBarLabel: I18n.t('investment.all'),
}
},
toBePaidBills: {
screen: MyList,
navigationOptions: {
tabBarLabel: I18n.t('investment.to_be_paid')
}
},
paidBills: {
screen: MyList,
navigationOptions: {
tabBarLabel: I18n.t('investment.paid')
}
},
closedBills: {
screen: MyList,
navigationOptions: {
tabBarLabel: I18n.t('investment.closed')
}
},
}, {
animationEnabled: true,
tabBarPosition: 'top', // 修改导航的位置
swipeEnabled: true,
tabBarOptions: {
// ...
}
});
MyList.js
,我在导航"didFocus"生活事件中更改了奇怪的名称,并且只通过axios
请求数据:
componentDidMount() {
appStorage.getUser().then(user => {
this.setState({ userId: user.user_id });
this.props.navigation.addListener('didFocus', this._onRefresh);
});
}
其次,我认为是因为组件卸载后没有取消http请求,所以我添加了axios cancelToken
。这是代码:
http请求方法:
getOrderArr(type, storage_user_id, page, callback, errCallback, navigation, listType) {
source = axios.CancelToken.source();
let that = this;
var query = this.setRequestData(type, page, listType);
var resOrderArr = [];
let config = {cancelToken: source.token};
InkubatorSApi.send({method: 'GET', url: query.url, obj: query.data, config: config}, (res) => {
if (axios.isCancel(res)) return;
// do something
}, navigation);
}
MyList.js
componentWillUnmount()
:
componentWillUnmount() {
source && source.cancel('Operation canceled by the user.');
this.navigationFocusEvent && this.navigationFocusEvent.remove();
}
最后,经过同样的操作,我使用iPhone在调试模式下运行应用程序。Xcode
控制台出现错误:
Assertion failed: (_lock_), function __SCNetworkReachabilityRestartResolver_block_invoke, file /BuildRoot/Library/Caches/com.apple.xbs/Sources/configd/configd-963.200.27/SystemConfiguration.fproj/SCNetworkReachability.c, line 1772.
(lldb)
同时,sentry
显示一个0http响应状态(这意味着请求不可访问(。以下是错误图片链接(我没有足够的信誉上传图片(:错误图像
所以我认为这可能是由IOS引起的,而不是我的代码。谁知道呢?