SKSTableView icon indicating copy to clipboard operation
SKSTableView copied to clipboard

BAD_ACCESS when expanding table view cell using 64-bit iPhone

Open jpgupta opened this issue 11 years ago • 16 comments

Hi - Love the control, just thought I'd share an issue that took me a while to figure out! Unfortunately I don't really know how to solve it but hopefully it'll help

When compiling with the "Standard Architectures + 64 bit" setting on my iPhone 5S, it crashes with a BAD_ACCESS exception when expanding a table view cell.

It occurs on SKSTableView.m line 705 (the objc_setAssociatedObject call in setSubRow: )

The problem, as far as I can see, is that under 64 bit architectures the subRowObj is being treated as a long instead of an int (which it is on 32 bit) as shown below

so_debug

I've changed my project settings to exclude 64 bit architectures (as in the sample app you provided) and its working fine now

jpgupta avatar Jan 18 '14 03:01 jpgupta

Thanks for the issue, i did not test the control for the 64-bit devices, my bad. But i will check the issue and fix the problem.

sakkaras avatar Jan 18 '14 09:01 sakkaras

See http://stackoverflow.com/a/21562526/1187415 for an analysis of the problem and a possible solution for 64-bit mode.

martinr448 avatar Feb 04 '14 23:02 martinr448

I temporarily fixed the issue by setting the subRow property as NSString not NSNumber. The explanation in the stackoverflow question helped me much, thank you. I will close this issue for now, but this problem will be in my mind.

sakkaras avatar Feb 07 '14 09:02 sakkaras

The bug is not fixed. It still crashes on 64-bit.

The problem is not that subRow is a NSNumber. The problem is that NSIndexPath ("self" in the setSubRow: method) is possibly a "tagged pointer" and setting an associated object on a tagged pointer crashes.

martinr448 avatar Feb 07 '14 13:02 martinr448

I may understand the problem wrong. However, i test the table in 64-bit iPhone simulator, it works fine. So, i considered it as resolved. You try it in simulator or the real device?

sakkaras avatar Feb 07 '14 13:02 sakkaras

I tested it in the 64-bit iPhone Simulator, and it crashes immediately if you expand a row. I changed the build architectures to "Standard Architectures (including 64-bit)" first, otherwise it is compiled for 32-bit only. - I cloned your repository and will try to check-in my fix. But I am still new to git and github, so this may take some time ...

martinr448 avatar Feb 07 '14 14:02 martinr448

Sorry about my answer, i forgot to change the build architecture (it does not include 64-bit). So, the problem does still exists.

sakkaras avatar Feb 07 '14 14:02 sakkaras

Is it resolved?

widmore avatar Mar 12 '14 19:03 widmore

ok guys , there is simple and elegant solution to solve this :) little explanation : On iOS for arm64, the isa field of Objective-C objects is no longer a pointer. Some of the bits still encode the pointer to the object's class. But neither OS X nor iOS actually uses all 64 bits of virtual address space. The Objective-C runtime may use these extra bits to store per-object data like its retain count or whether it has been weakly referenced. They changed "this" to 64bit becouse performance. Re-purposing these otherwise unused bits increases speed and decreases memory size. On iOS 7 the focus is on optimizing retain/release and alloc/dealloc.
from that REASON DON'T

  1. read obj->isa directly. The compiler will complain if you do. Trust the Compiler. The Compiler is your friend. Use [obj class] or object_getClass(obj) instead. 2.Don't write obj->isa directly. Use object_setClass() instead.

from that reason you need to change "way" you setting in 2 methods . example .

  • (NSInteger)subRow { id myclass = [SKSTableView class];

    id subRowObj = objc_getAssociatedObject(myclass, SubRowObjectKey); return [subRowObj integerValue]; }

  • (void)setSubRow:(NSInteger)subRow { id subRowObj = [NSNumber numberWithInteger:subRow];

    id myclass = [SKSTableView class];

    objc_setAssociatedObject(myclass, nil, subRowObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

} so put example for setSubRow and subRow , id myclass = [SKSTableView class]; objc_getAssociatedObject(myclass, SubRowObjectKey); and for objc_setAssociatedObject(myclass, nil, subRowObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

self-->isa IS PROBLEM on arm64 on iOS .

This works for 32bits and 64bit arch :)

tufnica avatar Apr 02 '14 13:04 tufnica

thank u so much this solve my problem in 64 bit and 32 bit

devil9677 avatar Jul 11 '14 07:07 devil9677

love u boss solved my problem

devil9677 avatar Jul 11 '14 07:07 devil9677

even after replacing the code I've got the same issue! any other solutions?

pradeepramalingam avatar Sep 16 '14 11:09 pradeepramalingam

The code works for me

mjspawn avatar Sep 25 '14 01:09 mjspawn

Thank u so much this solve my crash in iOS7.x

Lorwy avatar Jan 29 '15 08:01 Lorwy

Hi i am using this control is works fins but facing one issue i have added one button in cellForSubRowAtIndexPath when i clicked button the i got wrong row and subrow below is mu code

  • (UITableViewCell )tableView:(UITableView *)tableView cellForSubRowAtIndexPath:(NSIndexPath *)indexPath { UIButton *btn=(UIButton)[cell.contentView viewWithTag:15]; [btn addTarget:self action:@selector(DeleteClicked:) forControlEvents:UIControlEventTouchUpInside]; } -(void)DeleteClicked:(UIButton*)sender { CGPoint point=[sender convertPoint:CGPointZero toView:tbl_Preview]; indexpath=[tbl_Preview indexPathForRowAtPoint:point]; // i got wrong indexpath }

kirti301290 avatar Feb 11 '15 10:02 kirti301290

Same problem in iOS7 and it worked, Thks!

AresDev avatar Apr 16 '15 19:04 AresDev