I'm working on an iOS app with collectionView in objective-c and I have an error.
Below code is for feeding each cell with data(image in this case).
I pick up an image name from two dimensional array in Model class, and display it.
I made up a new array to prevent from duplication of image display by changing value in the array from '0' to '1' so next time can avoid display '1' marked image.
I succeeded initial setting all arrays with NSInteger 0, with replaceObjectAtIndex:withObject: method in a 'ViewDidLaod' method, however, I have an error when I want to change the value into '1' in the array with replaceObjectAtIndex:withObject:, the same method I used in the 'ViewDidLaod' method.
I already searched google and stack but people who got the same problem used immutable array, that's why they had an issue, but I have mutable array in my code. Please help me.
The error message is below:
2015-04-13 03:55:25.824 InfanTree[4474:166010] -[__NSCFNumber length]: unrecognized selector sent to instance 0xb000000000000002
2015-04-13 03:55:25.846 InfanTree[4474:166010] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber length]: unrecognized selector sent to instance 0xb000000000000002'
*** First throw call stack:
(
0 CoreFoundation 0x000000010826fa75 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000107f08bb7 objc_exception_throw + 45
2 CoreFoundation 0x0000000108276d1d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x00000001081ce9dc ___forwarding___ + 988
4 CoreFoundation 0x00000001081ce578 _CF_forwarding_prep_0 + 120
5 UIKit 0x0000000108f13f06 +[_UIAssetManager createAssetNamed:fromBundle:] + 67
6 UIKit 0x00000001088d4f60 +[UIImage imageNamed:inBundle:compatibleWithTraitCollection:] + 221
7 InfanTree 0x00000001079c92d0 -[ViewController collectionView:cellForItemAtIndexPath:] + 512
8 UIKit 0x0000000108ed1fab -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:] + 244
9 UIKit 0x0000000108ed36e4 -[UICollectionView _updateVisibleCellsNow:] + 3445
10 UIKit 0x0000000108ed7391 -[UICollectionView layoutSubviews] + 243
11 UIKit 0x000000010891c1c3 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 521
12 QuartzCore 0x000000010cc5ac58 -[CALayer layoutSublayers] + 150
13 QuartzCore 0x000000010cc4f87e _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
14 QuartzCore 0x000000010cc4f6ee _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
15 QuartzCore 0x000000010cbbd36e _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
16 QuartzCore 0x000000010cbbe482 _ZN2CA11Transaction6commitEv + 390
17 UIKit 0x00000001088a068d -[UIApplication _reportMainSceneUpdateFinished:] + 44
18 UIKit 0x00000001088a1375 -[UIApplication _runWithMainScene:transitionContext:completion:] + 2684
19 UIKit 0x000000010889fd35 -[UIApplication workspaceDidEndTransaction:] + 179
20 FrontBoardServices 0x000000010bd92243 __31-[FBSSerialQueue performAsync:]_block_invoke + 16
21 CoreFoundation 0x00000001081a4c7c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
22 CoreFoundation 0x000000010819a9c5 __CFRunLoopDoBlocks + 341
23 CoreFoundation 0x000000010819a183 __CFRunLoopRun + 851
24 CoreFoundation 0x0000000108199bc6 CFRunLoopRunSpecific + 470
25 UIKit 0x000000010889f7a2 -[UIApplication _run] + 413
26 UIKit 0x00000001088a2580 UIApplicationMain + 1282
27 InfanTree 0x00000001079d19d3 main + 115
28 libdyld.dylib 0x000000010aa60145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Whole code is here
Below is part of my code.
#interface ViewController ()<UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>
{
DataModel *_data;
// save the indexPath value itself of the picture which is selected at specific index path
NSMutableArray *_displayedImageIndexPathHistory;
// save 1 for the first rendering so next time can avoid to be selected
NSMutableArray *_isSelectedBefore;
// save 1 if rendered at least once so can avoid duplication
NSMutableArray *_preventDuplication;
}
#end
#implementation ViewController
.
.
.
- (void)viewDidLoad {
[super viewDidLoad];
.
.
.
// _data.imageSet is a two dimensional 'MUTABLE' array which has 'MUTABLE' arrays in it.
// Declared in a Model class. Each element has NSString *imageName.png.
_preventDuplication = [_data.imageSet mutableCopy];
_displayedImageIndexPathHistory = [_data.imageSet mutableCopy];
_isSelectedBefore = [_data.imageSet mutableCopy];
// set all arrays with 0
NSInteger sectionNum = [_data.imageSet count];
NSNumber *defaultNumber = [NSNumber numberWithInt:0];
for (NSInteger i = 0; i < sectionNum; i++) {
for (NSInteger j = 0; j < [_data.imageSet[i] count]; j++) {
[_displayedImageIndexPathHistory[i] replaceObjectAtIndex:j withObject:defaultNumber];
[_isSelectedBefore[i] replaceObjectAtIndex:j withObject:defaultNumber];
[_preventDuplication[i] replaceObjectAtIndex:j withObject:defaultNumber];
}
}
.
.
.
}
.
.
.
-(UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CollectionViewCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
NSNumber *defaultNumber = [NSNumber numberWithInt:0];
NSNumber *markingNumber = [NSNumber numberWithInt:1];
if (indexPath.row == 0) {
cell.cellImageView.image = [UIImage imageNamed:[_data.imageSet[indexPath.section] objectAtIndex:indexPath.row]];
// **Have error at this sentence!!**
[_preventDuplication[indexPath.section] replaceObjectAtIndex:indexPath.row withObject: markingNumber];
}
else {
.
.
.
}
.
.
return cell;
}
Thanks in advance.
Your code has the expression:
[UIImage imageNamed:[_data.imageSet[indexPath.section] objectAtIndex:indexPath.row]]
It would seem that this part:
[_data.imageSet[indexPath.section] objectAtIndex:indexPath.row]
Is producing an instance of NSNumber, not an instance of NSString. Of course, +[UIImage imageNamed:] requires its argument to be a string. It's apparently invoking -length on it. Since NSNumber doesn't respond to -length, you get that exception and crash.
Related
This my code ,i am removing multiple values on my condition
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
PhotoCan *cell=[collectionView cellForItemAtIndexPath:indexPath];
UIImage *getimg=[dicPhotoStore objectForKey:#(indexPath.row)];
BOOL integer=[dic objectForKey:#(indexPath.row)];
if(integer)
{
for(id img in arrFinalStore)
{
if(img==getimg)
{
NSLock *arrayLock = [[NSLock alloc] init];
[arrayLock lock];
[arrFinalStore removeObject:img];
NSLog(#"crash inside");
[arrayLock unlock];
}
}
#synchronized(self)
{
[dic removeObjectForKey:#(indexPath.row)];
[dicPhotoStore removeObjectForKey:#(indexPath.row)];
}
NSLog(#"crashoutside");
NSLog(#"inside false");
}
else
{
[dicPhotoStore setObject:cell.imgView.image forKey:#(indexPath.row)];
[arrFinalStore addObject:cell.imgView.image];
[dic setObject:#"1" forKey:#(indexPath.row)];
}
[_collection reloadData];
}
I am understood something goes wrong trying to find out this error ,please help me to overcome this .
This is error :
*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x7f881a6b1900> was mutated while being enumerated.'
*** First throw call stack:
(
0 CoreFoundation 0x000000010299fe65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000102418deb objc_exception_throw + 48
2 CoreFoundation 0x000000010299f7c4 __NSFastEnumerationMutationHandler + 132
3 PhotoCollageCanvas 0x000000010056878f -[photoAssets collectionView:didSelectItemAtIndexPath:] + 767
4 UIKit 0x0000000103afb4a7 -[UICollectionView _selectItemAtIndexPath:animated:scrollPosition:notifyDelegate:] + 701
5 UIKit 0x0000000103b1d049 -[UICollectionView touchesEnded:withEvent:] + 574
6 UIKit 0x00000001034b6ef7 forwardTouchMethod + 349
7 UIKit 0x00000001034b6fc0 -[UIResponder touchesEnded:withEvent:] + 49
8 UIKit 0x00000001034b6ef7 forwardTouchMethod + 349
9 UIKit 0x00000001034b6fc0 -[UIResponder touchesEnded:withEvent:] + 49
10 UIKit 0x0000000103783ede _UIGestureRecognizerUpdate + 10279
11 UIKit 0x0000000103319f8a -[UIWindow _sendGesturesForEvent:] + 1137
12 UIKit 0x000000010331b1c0 -[UIWindow sendEvent:] + 849
13 UIKit 0x00000001032c9b66 -[UIApplication sendEvent:] + 263
14 UIKit 0x00000001032a3d97 _UIApplicationHandleEventQueue + 6844
15 CoreFoundation 0x00000001028cba31 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
16 CoreFoundation 0x00000001028c195c __CFRunLoopDoSources0 + 556
17 CoreFoundation 0x00000001028c0e13 __CFRunLoopRun + 867
18 CoreFoundation 0x00000001028c0828 CFRunLoopRunSpecific + 488
19 GraphicsServices 0x00000001058d8ad2 GSEventRunModal + 161
20 UIKit 0x00000001032a9610 UIApplicationMain + 171
21 Photo 0x0000000100566a5f main + 111
22 libdyld.dylib 0x000000010697b92d start + 1
23 ??? 0x0000000000000001 0x0 + 1
)
What do you think that lock would do? It does exactly nothing. You created a lock, locked it, unlocked it. Since that code is the only code with access to the lock, that lock cannot possibly prevent anyone from doing anything.
And it wouldn't solve your problem anyway. Someone is enumerating that array. Any attempt to modify it, as you are trying, while it is enumerated, will crash.
Your code is (with lines removed)
for(id img in arrFinalStore)
{
[arrFinalStore removeObject:img];
}
That code is absolutely going to crash, and there is nothing that can stop it from crashing. You cannot remove an object from an array while iteration.
You cannot remove element while iterating through array
[arrFinalStore removeObject:img];
just use [arrFinalStore removeObject:img];
You cannot remove element while iterating through array, so you can create temp array with all unnecessary objects and then call - (void)removeObjectsInArray:(NSArray<ObjectType> *)otherArray
So your code is:
NSMutableArray *tempArray = [NSMutableArray array];
for(id img in arrFinalStore)
{
if(img==getimg)
{
[tempArray addObject:img];
}
}
[arrFinalStore removeObjectsInArray:tempArray];
also you can use simple for (int i = arrfinalstoer.count - 1; i > 0; --i) for enumeration.
Its not the issue with the lock. But the issue is while iterating you are trying to remove the element which means you doing concurrent modification which throws exception.
here is an example you can use
for (item in originalArrayOfItems) {
if ([item shouldBeDiscarded])
[discardedItems addObject:item];}
[originalArrayOfItems removeObjectsInArray:discardedItems];
I have a custom class oject that I want to save using NSUserDefaults, this is how I saving it:
Shift.m
-(void)encodeWithCoder:(NSCoder*)encoder
{
[encoder encodeObject:self.date forKey:#"date"];
[encoder encodeObject:self.startTime forKey:#"startTime"];
[encoder encodeObject:self.endTime forKey:#"endTime"];
}
- (id)initWithCoder:(NSCoder *)decoder {
if(self = [super init]) {
self.date = [decoder decodeObjectForKey:#"date"];
self.startTime = [decoder decodeObjectForKey:#"startTime"];
self.endTime = [decoder decodeObjectForKey:#"endTime"];
}
return self;
}
MyTableViewController.m:
-(void)saveCustomObject:(id)object forKey:(NSString*)key
{
NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:object];
[[NSUserDefaults standardUserDefaults] setObject:encodedObject forKey:key];
}
-(NSArray*)getCustomObjectForKey:(NSString*)key
{
NSData *encodedObject = [[NSUserDefaults standardUserDefaults] objectForKey:key];
NSArray *shifts=[NSArray arrayWithObjects:[NSKeyedUnarchiver unarchiveObjectWithData:encodedObject], nil];
return shifts;
}
It seems it works fine when debugging, but when I try to access one of the object properties, for example on tableView: cellForRowAtIndexPath: like that:
Shift *currentShift=[self.shifts objectForIndex:indexPath.row];
NSLog(#"%#",currentShift.startTime.description);
It crashes with that crash message:
2016-03-19 09:04:05.913 MyApp[9654:4249448] -[__NSArrayM startTime]: unrecognized selector sent to instance 0x7ff81b449c10
2016-03-19 09:04:05.924 MyApp[9654:4249448] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM startTime]: unrecognized selector sent to instance 0x7ff81b449c10'
*** First throw call stack:
(
0 CoreFoundation 0x000000010e3e9e65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010de62deb objc_exception_throw + 48
2 CoreFoundation 0x000000010e3f248d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x000000010e33f90a ___forwarding___ + 970
4 CoreFoundation 0x000000010e33f4b8 _CF_forwarding_prep_0 + 120
5 Mehuyavut count 0x000000010d95a8e8 -[shiftsTableViewViewController tableView:cellForRowAtIndexPath:] + 600
6 UIKit 0x000000010e8efe43 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 766
7 UIKit 0x000000010e8eff7b -[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 74
8 UIKit 0x000000010e8c4a39 -[UITableView _updateVisibleCellsNow:isRecursive:] + 2996
9 UIKit 0x000000010e8f901c -[UITableView _performWithCachedTraitCollection:] + 92
10 UIKit 0x000000010e8dfedc -[UITableView layoutSubviews] + 224
11 UIKit 0x000000010e84d4a3 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 703
12 QuartzCore 0x000000011231959a -[CALayer layoutSublayers] + 146
13 QuartzCore 0x000000011230de70 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 366
14 QuartzCore 0x000000011230dcee _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
15 QuartzCore 0x0000000112302475 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 277
16 QuartzCore 0x000000011232fc0a _ZN2CA11Transaction6commitEv + 486
17 QuartzCore 0x000000011233037c _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 92
18 CoreFoundation 0x000000010e315367 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
19 CoreFoundation 0x000000010e3152d7 __CFRunLoopDoObservers + 391
20 CoreFoundation 0x000000010e30af2b __CFRunLoopRun + 1147
21 CoreFoundation 0x000000010e30a828 CFRunLoopRunSpecific + 488
22 GraphicsServices 0x0000000111ba6ad2 GSEventRunModal + 161
23 UIKit 0x000000010e796610 UIApplicationMain + 171
24 Mehuyavut count 0x000000010d95b5af main + 111
25 libdyld.dylib 0x0000000110b2592d start + 1
26 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Any one knows why?
Thank you!
It seems like you want Shift *currentShift=[self.shifts objectForIndex:indexPath.row] to give you 1 Shift object, but what it really does is returning a NSArray. You basically call a startTime method in NSArray, and since it doesn't exist, your program fails.
It seems like NSLog(#"%#",currentShift.startTime.description) is the line doing that. Confirm by commenting out the NSLog. It shouldn't give you a crash.
If this hypothesis is fine, check if [currentShift isKindOfClass:[NSArray class]] is true.
If it is, a bug you have in this line:
NSArray *shifts=[NSArray arrayWithObjects:[NSKeyedUnarchiver unarchiveObjectWithData:encodedObject], nil];
You also don't really show how your - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section looks like. You must return proper number of entries there.
You're making self.shifts be an NSArray, but you use objectForKey, which is available for dictionaries. It's not available for arrays. I think you wanted objectAtIndex instead.
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?
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;
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);
}
I have an NSMutableArray that I have build up that consists or holds a NSMutableDictionary.
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
self.userNameArray = [NSMutableArray arrayWithArray:[userDefaults arrayForKey:#"userNameTextArray"]];
NSMutableArray *arrayToAdd = [[NSMutableArray alloc] init];
for (id object in self.userNameArray) {
[arrayToAdd addObject:#"Negative"];
}
self.namesDictionary = [#{ #"userNameText" : self.categoriesMutableNameArray, #"selectedCellState" : arrayToAdd}mutableCopy];
self.namesFinalArr = [[NSMutableArray alloc] init];
self.namesDictMutableDict = [NSMutableDictionary dictionaryWithDictionary:self.namesDictionary];
[self.namesFinalArr addObject:self.namesDictMutableDict];
The result in my NSlog of the above code is like this:
(
{
selectedCellState = (
Negative,
Negative,
Negative,
Negative,
Negative,
Negative,
Negative,
Negative,
Negative,
Negative,
Negative,
Negative,
Negative,
Negative
);
userNameText = (
"userText - Text",
"userText1 - Text1",
"userText2 - Text2",
"userText3 - Text3",
"userText4 - Text4",
"userText5 - Text5",
"userText6 - Text6",
"userText7 - Text7",
"userText8 - Text8",
"userText9 - Text9",
"userText10 - Text10",
"userText11 - Text11",
"userText12 - Text12",
"userText13 - Text13"
);
}
)
I am using a UITableview and I populate the UITableview with self.namesFinalArr . in the CellForRow method like this and it works:
labelForTableCell.text = [[[self.namesFinalArr objectAtIndex:0] objectForKey:#"userNameText"]objectAtIndex:indexPath.row];
This populates my UITableview with the data under userNameText in self.namesFinalArr
I am trying to enable or disable an image on a cell when it is selected and I use the didDeselectRowAtIndexPath and didselectRowAtIndexPath methods to show and hide a UImageview
This works but I am trying to update selectedCellState in self.namesFinalArr at the index row or row that was pressed but I get the following error.
In the didselectRowAtIndexPath method I do something like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.selectedRows = [self.tableView indexPathsForSelectedRows];
[[[[self.namesFinalArr objectAtIndex:0] objectForKey:#"selectedCellState"]objectAtIndex:indexPath.row] setValue:#"Positive" forKey:#"selectedCellState"];
}
When trying to change the array value and index row I get a error:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFConstantString 0x23fef0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key selectedCellState.'
*** First throw call stack:
(
0 CoreFoundation 0x020c75e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x01e4a8b6 objc_exception_throw + 44
2 CoreFoundation 0x021576a1 -[NSException raise] + 17
3 Foundation 0x0075d9ee -[NSObject(NSKeyValueCoding) setValue:forUndefinedKey:] + 282
4 Foundation 0x006c9cfb _NSSetUsingKeyValueSetter + 88
5 Foundation 0x006c9253 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 267
6 Piccing 0x0004880c -[PiccImageCategoriesViewController tableView:didSelectRowAtIndexPath:] + 828
7 UIKit 0x010a77b1 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1513
8 UIKit 0x010a7924 -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 279
9 UIKit 0x010ab908 __38-[UITableView touchesEnded:withEvent:]_block_invoke + 43
10 UIKit 0x00fe2183 ___afterCACommitHandler_block_invoke + 15
11 UIKit 0x00fe212e _applyBlockToCFArrayCopiedToStack + 403
12 UIKit 0x00fe1f5a _afterCACommitHandler + 532
13 CoreFoundation 0x0208f4ce __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
14 CoreFoundation 0x0208f41f __CFRunLoopDoObservers + 399
15 CoreFoundation 0x0206d344 __CFRunLoopRun + 1076
16 CoreFoundation 0x0206cac3 CFRunLoopRunSpecific + 467
17 CoreFoundation 0x0206c8db CFRunLoopRunInMode + 123
18 GraphicsServices 0x027779e2 GSEventRunModal + 192
19 GraphicsServices 0x02777809 GSEventRun + 104
20 UIKit 0x00fc5d3b UIApplicationMain + 1225
21 Piccing 0x000138cd main + 141
22 libdyld.dylib 0x02f4d70d start + 1
23 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
In this case,there is one array which contains two dictionary each contains array and you are suppose to change the values in array and you should used this method to change the value
[[[self.namesFinalArr objectAtIndex:0] objectForKey:#"selectedCellState"] replaceObjectAtIndex:indexPath.row withObject:#"Positive"];
I have a NSDictionary that I add to a mutable array but when I try add the array to populate a uitableview I get an error.
NSMutableArray *array = [[NSMutableArray alloc] init];
for (id element in self.categoriesMutableNameArray) {
[array addObject:#"No"];
}
self.categoryDict = #{ #"title" : self.categoriesMutableNameArray, #"selected" : array};
self.categoryArr = [[NSMutableArray alloc] init];
self.categoryMutableDict = [NSMutableDictionary dictionaryWithDictionary:self.categoryDict];
[self.categoryArr addObject:self.categoryDict];
and the following categoryArr is printed like this:
2014-02-27 15:09:07.397 App[7982:70b] (
{
selected = (
No,
No,
No,
No,
No,
No,
No,
No,
No,
No,
No,
No,
No,
No
);
title = (
"Fashion - Women",
"Fashion - Men",
Kids,
"Accessories - Women",
"Accessories - Men",
"Styling / Hair",
Inspiration,
"Decoration / Architecture",
"Great Places",
"Art / Design",
"Music / Movie / Books",
"Food / Drink",
"Gadgets / Tech",
Rides
);
}
)
The trouble I am having is in the uitableview cellforrowatindexpath method I try and add the title key for the categoryArr to populate the uitableview and I get the following error on this line:
UILabel *categoryLabel = (UILabel *)[cell viewWithTag:111];
categoryLabel.text = [NSString stringWithFormat:#"%#",[[self.categoryArr objectAtIndex:indexPath.row] objectForKey:#"title"];
And the error log:
2014-02-27 15:24:33.804 App[8153:70b] -[__NSArrayM length]: unrecognized selector sent to instance 0xa9bc3a0
2014-02-27 15:24:33.807 App[8153:70b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM length]: unrecognized selector sent to instance 0xa9bc3a0'
*** First throw call stack:
(
0 CoreFoundation 0x020c75e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x01e4a8b6 objc_exception_throw + 44
2 CoreFoundation 0x02164903 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x020b790b ___forwarding___ + 1019
4 CoreFoundation 0x020b74ee _CF_forwarding_prep_0 + 14
5 Foundation 0x006e18ed -[NSConcreteMutableAttributedString replaceCharactersInRange:withString:] + 39
6 Foundation 0x006e255a -[NSConcreteMutableAttributedString initWithString:attributes:] + 293
7 UIKit 0x01172bc6 -[UILabel _setText:] + 97
8 UIKit 0x01172d84 -[UILabel setText:] + 40
9 App 0x00047ebd -[PiccImageCategoriesViewController tableView:cellForRowAtIndexPath:] + 1533
10 UIKit 0x010b461f -[UITableView _createPreparedCellForGlobalRow:withIndexPath:] + 412
11 UIKit 0x010b46f3 -[UITableView _createPreparedCellForGlobalRow:] + 69
12 UIKit 0x01098774 -[UITableView _updateVisibleCellsNow:] + 2378
13 UIKit 0x010abe95 -[UITableView layoutSubviews] + 213
14 UIKit 0x01030267 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 355
15 libobjc.A.dylib 0x01e5c81f -[NSObject performSelector:withObject:] + 70
16 QuartzCore 0x00c8e2ea -[CALayer layoutSublayers] + 148
17 QuartzCore 0x00c820d4 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
18 QuartzCore 0x00c81f40 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 26
19 QuartzCore 0x00be9ae6 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 294
20 QuartzCore 0x00beae71 _ZN2CA11Transaction6commitEv + 393
21 QuartzCore 0x00beb544 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 92
22 CoreFoundation 0x0208f4ce __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
23 CoreFoundation 0x0208f41f __CFRunLoopDoObservers + 399
24 CoreFoundation 0x0206d344 __CFRunLoopRun + 1076
25 CoreFoundation 0x0206cac3 CFRunLoopRunSpecific + 467
26 CoreFoundation 0x0206c8db CFRunLoopRunInMode + 123
27 GraphicsServices 0x027779e2 GSEventRunModal + 192
28 GraphicsServices 0x02777809 GSEventRun + 104
29 UIKit 0x00fc5d3b UIApplicationMain + 1225
30 App 0x0001406d main + 141
31 libdyld.dylib 0x02f4d70d start + 1
32 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
Thanks
The return of [[self.categoryArr objectAtIndex:indexPath.row] objectForKey:#"title"]; is a array of NSString, categoryLabel.text = [NSString stringWithFormat:#"%#", /*the return array*/]; this is the problem.
Maybe what you want is:
NSArray *categoryDetailArr = [[self.categoryArr objectAtIndex:indexPath.section] objectForKey:#"title"];
categoryLabel.text = [[categoryDetailArr objectAtIndex:indexPath.row];
Write this code
categoryLabel.text = [[[self.categoryArr objectAtIndex:0] objectForKey:#"title"]objectAtIndex:indexPath.row];
instead OF
categoryLabel.text = [NSString stringWithFormat:#"%#",[[self.categoryArr objectAtIndex:indexPath.row] objectForKey:#"title"];
And plz check that in UITableView dataSource methods i.e
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [categoryLabel objectAtIndex:0]valueForKey:#"selected"].count;
}
OR
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [categoryLabel objectAtIndex:0]valueForKey:#"title"].count;
}