Mehdi Ijadnazar
Mehdi Ijadnazar

Reputation: 4951

unrecognized selector sent to instance thrown in a strange way

I have a tableView which should load its cells with data from server.
When my data is loaded from server I call [self.tableView reloadData] inside completionhandler block.
So the method cellForRowAtIndexPath gets called again.
My implementation for cellForRowAtIndexPath is this:

- (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;
}

Note: self.newsList is an array that is populated with data from server
The code that parses response json from server is this:

        [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);
        }];

My problem: When I debug this code the cell variable I create using dequeueReusableCellWithIdentifier:forIndexPath function is null in the debugger's variables section, but when I use lldb command po to print it out I get this

(lldb) po cell
<NewsCell: 0x7fc5fadb2ee0; baseClass = UITableViewCell; frame = (0 0; 375 143); autoresize = W; layer = <CALayer: 0x7fc5fad9fcd0>>

The same happens for currentNews variable. For it I get this from po command

(lldb) po currentNews
<News: 0x7fc5fd0480d0>        

I even can get properties on it like this:

(lldb) po currentNews.title
<__NSCFArray 0x7fc5fd047300>(
                             "some title"
                             )

There is no exception when stepping through this method's statements. But when the method returns the Unrecognized Selector exception is thrown Why this happens??

The Strange thing is that if I change this line:

cell.newsTitle.text = currentNews.title;

to this:

cell.newsTitle.text = @"Some test text";

everything goes well, specifically the cell and currentNews variables are not null anymore and tableView renders the cells without any problem

The full stack trace is :

    [__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

)

Can anybody tell me the reason for this?

Upvotes: 0

Views: 211

Answers (2)

Dipen Panchasara
Dipen Panchasara

Reputation: 13600

It simply indicates at some point when you try to access title value in currentNews object, it would be null. thats why your app throws exception. put a condition to check null value.

Use following method to check any value/object exist or not.

Usage

write following code in your cellForRowAtIndexPath method.

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);
}

Upvotes: -1

Mats
Mats

Reputation: 8628

The server JSON is an array of a string, ["some title"], and you expect it to be just a string "some title".

Try adding an assertion so that your parsing of the server data is correct.

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;

Upvotes: 3

Related Questions