Ios 发送到以奇怪方式抛出的实例的无法识别的选择器
我有一个tableView,它应该在单元格中加载来自服务器的数据。Ios 发送到以奇怪方式抛出的实例的无法识别的选择器,ios,objective-c,uitableview,unrecognized-selector,Ios,Objective C,Uitableview,Unrecognized Selector,我有一个tableView,它应该在单元格中加载来自服务器的数据。 从服务器加载数据时,我在completionhandler块内调用[self.tableView reloadData]。 因此会再次调用CellForRowatineXpath方法。 我对cellForRowAtIndexPath的实现如下: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)
从服务器加载数据时,我在completionhandler块内调用[self.tableView reloadData]。
因此会再次调用CellForRowatineXpath方法。
我对cellForRowAtIndexPath的实现如下:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Configure the cell...
NewsCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"NewsCell" forIndexPath:indexPath];
if(!cell){
cell = [[NewsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"NewsCell"];
}
News* currentNews = (News*)[self.newsList objectAtIndex:indexPath.row];
cell.newsTitle.text = currentNews.title;
// cell.newsTitle.text = @"salam";
return cell;
}
[GNetworkHelper getJsonDataFromURL:urlString
withCompletionHandler:^(NSDictionary * jsonResponse) {
// Parse retrieved json and pass it to completion handler;;
NSMutableArray* news = [[NSMutableArray alloc] init];
if (jsonResponse) {
for (NSDictionary* new in jsonResponse) {
News *currentNew = [[News alloc] initWithDictionary:new];
[news addObject:currentNew];
}
}else{
News* testNew = [[News alloc] init];
[testNew setTitle:@"salam"];
[news addObject:testNew];
}
completionHandler(news);
}];
注意:self.newsList是一个用来自服务器的数据填充的数组解析来自服务器的响应json的代码如下:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Configure the cell...
NewsCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"NewsCell" forIndexPath:indexPath];
if(!cell){
cell = [[NewsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"NewsCell"];
}
News* currentNews = (News*)[self.newsList objectAtIndex:indexPath.row];
cell.newsTitle.text = currentNews.title;
// cell.newsTitle.text = @"salam";
return cell;
}
[GNetworkHelper getJsonDataFromURL:urlString
withCompletionHandler:^(NSDictionary * jsonResponse) {
// Parse retrieved json and pass it to completion handler;;
NSMutableArray* news = [[NSMutableArray alloc] init];
if (jsonResponse) {
for (NSDictionary* new in jsonResponse) {
News *currentNew = [[News alloc] initWithDictionary:new];
[news addObject:currentNew];
}
}else{
News* testNew = [[News alloc] init];
[testNew setTitle:@"salam"];
[news addObject:testNew];
}
completionHandler(news);
}];
我的问题:当我调试这段代码时,我使用dequeueReusableCellWithIdentifier:forIndexPath函数创建的单元格变量在调试器的变量部分为空,但当我使用lldb命令po将其打印出来时,我得到以下结果:
(lldb) po cell
<NewsCell: 0x7fc5fadb2ee0; baseClass = UITableViewCell; frame = (0 0; 375 143); autoresize = W; layer = <CALayer: 0x7fc5fad9fcd0>>
为此:
cell.newsTitle.text = @"Some test text";
一切进展顺利,特别是单元格和当前新闻变量不再为空,tableView呈现单元格时没有任何问题
完整堆栈跟踪是:
[__NSCFArray length]: unrecognized selector sent to instance 0x7fc5fd047300
2015-09-16 11:30:40.630 Gallery[12013:952548] Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFArray length]: unrecognized selector sent to instance 0x7fc5fd047300'
--- First throw call stack:
(
0 CoreFoundation 0x0000000105af3f35 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010578cbb7 objc_exception_throw + 45
2 CoreFoundation 0x0000000105afb04d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x0000000105a5327c ___forwarding___ + 988
4 CoreFoundation 0x0000000105a52e18 _CF_forwarding_prep_0 + 120
5 UIKit 0x00000001060a5f45 -[UILabel _textRectForBounds:limitedToNumberOfLines:includingShadow:] + 65
6 UIKit 0x00000001060a5da0 -[UILabel textRectForBounds:limitedToNumberOfLines:] + 76
7 UIKit 0x00000001060a9852 -[UILabel _intrinsicSizeWithinSize:] + 170
8 UIKit 0x00000001060a9932 -[UILabel intrinsicContentSize] + 76
9 UIKit 0x000000010655fea4 -[UIView(UIConstraintBasedLayout) _generateContentSizeConstraints] + 33
10 UIKit 0x000000010655fc64 -[UIView(UIConstraintBasedLayout) _updateContentSizeConstraints] + 422
11 UIKit 0x00000001065670d6 -[UIView(AdditionalLayoutSupport) updateConstraints] + 163
12 UIKit 0x00000001060a979d -[UILabel updateConstraints] + 272
13 UIKit 0x00000001065666fa -[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 248
14 UIKit 0x00000001065668f2 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 124
15 CoreFoundation 0x00000001059fc194 CFArrayApplyFunction + 68
16 UIKit 0x000000010656669b -[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 153
17 Foundation 0x0000000105332d6e -[NSISEngine withBehaviors:performModifications:] + 155
18 UIKit 0x00000001065668f2 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 124
19 CoreFoundation 0x00000001059fc194 CFArrayApplyFunction + 68
20 UIKit 0x000000010656669b -[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 153
21 UIKit 0x00000001065668f2 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 124
22 UIKit 0x0000000106566dbe __60-[UIView(AdditionalLayoutSupport) updateConstraintsIfNeeded]_block_invoke + 96
23 UIKit 0x0000000106566a86 -[UIView(AdditionalLayoutSupport) updateConstraintsIfNeeded] + 231
24 UIKit 0x000000010635c8b8 -[UITableViewCellContentView updateConstraintsIfNeeded] + 95
25 UIKit 0x000000010656719e -[UIView(AdditionalLayoutSupport) _updateConstraintsAtEngineLevelIfNeeded] + 159
26 UIKit 0x0000000105f4db2d -[UIView(Hierarchy) _updateConstraintsAsNecessaryAndApplyLayoutFromEngine] + 114
27 UIKit 0x0000000105f59973 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 521
28 QuartzCore 0x000000010504ade8 -[CALayer layoutSublayers] + 150
29 QuartzCore 0x000000010503fa0e _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
30 QuartzCore 0x000000010503f87e _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
31 QuartzCore 0x0000000104fad63e _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
32 QuartzCore 0x0000000104fae74a _ZN2CA11Transaction6commitEv + 390
33 QuartzCore 0x0000000104faedb5 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 89
34 CoreFoundation 0x0000000105a28dc7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
35 CoreFoundation 0x0000000105a28d20 __CFRunLoopDoObservers + 368
36 CoreFoundation 0x0000000105a1eb53 __CFRunLoopRun + 1123
37 CoreFoundation 0x0000000105a1e486 CFRunLoopRunSpecific + 470
38 GraphicsServices 0x00000001085d29f0 GSEventRunModal + 161
39 UIKit 0x0000000105ee0420 UIApplicationMain + 1282
40 Gallery 0x000000010346ded3 main + 115
41 libdyld.dylib 0x0000000107325145 start + 1
42 ??? 0x0000000000000001 0x0 + 1
)
有人能告诉我这是什么原因吗?它只是指出,在某个时候,当您试图访问
currentNews
对象中的title
值时,它将是null
。这就是你的应用程序抛出异常的原因。设置条件以检查null
值
使用以下方法检查是否存在任何值/对象
用法
在cellforrowatinexpath
方法中编写以下代码
if([self isEmpty:currentNews.title])
{
cell.newsTitle.text = @"default value";
}
else
{
cell.newsTitle.text = currentNews.title[0];
}
// Method to check empty value/object
- (BOOL)isEmpty:(id)object
{
return object == nil
|| [object isKindOfClass:[NSNull class]]
|| ([object respondsToSelector:@selector(length)]
&& [(NSData *)object length] == 0)
|| ([object respondsToSelector:@selector(count)]
&& [(NSArray *)object count] == 0);
}
服务器JSON是一个字符串数组,
[“some title”]
,您希望它只是一个字符串“some title”
尝试添加断言,以便正确解析服务器数据
News* currentNews = (News*)[self.newsList objectAtIndex:indexPath.row];
NSAssert([currentNews.title isKindOfClass:[NSString class]],
@"Title is not a string but a %@.",
NSStringFromClass([currentNews.title class]));
cell.newsTitle.text = currentNews.title;
它只是指示当您尝试访问
currentNews
对象中的title
值时,它将是null
。这就是你的应用程序抛出异常的原因。设置一个检查空值的条件。您可以在completionHandler中发布代码吗?似乎currentNews
处于活动状态,但其标题属性已解除分配(如果其标题属性设置为NSString)。我已发布详细答案@Mahdi.Post完整崩溃文本。@Mahdi将currentNews.title
行替换为currentNews.title[0]
那么你是说当currentNews==nil
时调用currentNews.title
会导致异常?根据OPs解释title
是null
并导致崩溃。将nil
分配给标签的文本属性不会引发无法识别的选择器
异常。根据他的解释llbd
logstitle
值位于NSArray
notNSString
对象的News
中,因为OP试图将其作为字符串访问,这会导致崩溃。断言失败,出现异常,它说“标题不是一个字符串,而是一个_unscfarray”。在我解析json响应时会发生这种情况吗?我认为您的json解析代码中有一个错误。它应该验证currentNews.title
是一个NSString
。谢谢Mats,你的回答绝对正确。我纠正了完成处理程序的json解析部分,所有问题都解决了。
News* currentNews = (News*)[self.newsList objectAtIndex:indexPath.row];
NSAssert([currentNews.title isKindOfClass:[NSString class]],
@"Title is not a string but a %@.",
NSStringFromClass([currentNews.title class]));
cell.newsTitle.text = currentNews.title;