React Native IOS应用程序崩溃,用NULL调用CFRelease()



我无法在调试模型中重现错误。但在发布的应用程序中,使用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.jscomponentWillUnmount():

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引起的,而不是我的代码。谁知道呢?

最新更新