在64位模式objc_setAssociatedObject功能错误不是在32位 [英] objc_setAssociatedObject function error in 64bit mode not in 32bit

查看:610
本文介绍了在64位模式objc_setAssociatedObject功能错误不是在32位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是用我的项目一个整洁的表视图控制器名为 SKSTableView ,允许每个表行有若干子行。这code完全在 32位的模式,但是当我在我的iPhone 5S或模拟器的4英寸64位模式下,当你点击一排得到它崩溃的子行运行。我没有对64位和32位的iOS系统的差异的任何知识。我很想了解它发生在这里。

I am using a neat table view controller called SKSTableView in my project which allows each table row to have a number of sub rows. This code works perfectly in 32bit mode but when I run it on my iPhone 5S or in the Simulator in 4-inch 64bit mode, when you tap on a row to get the sub rows it crashes. I do not have any knowledge of the differences of 64bit and 32bit iOS systems. I would love to understand what it happening here.

您会发现,* SubRowObjectKey设置为无空隙,我得到的错误: EXC_BAD_ACCESS _(code = EXC_I386_GPFLT)
这是一个一般性保护错误试图访问的东西是不存在(?)

You will notice that the *SubRowObjectKey is set to void- the error I get is: EXC_BAD_ACCESS_(code=EXC_I386_GPFLT)
Which is a general protection fault trying to access something that is not there(?)

当它崩溃X $ C $Ç亮点此行code:
objc_setAssociatedObject(个体经营,SubRowObjectKey,subRowObj,OBJC_ASSOCIATION_ASSIGN);

When it crashes Xcode highlights this line of code:
objc_setAssociatedObject(self, SubRowObjectKey, subRowObj, OBJC_ASSOCIATION_ASSIGN);

也有是这样的: 印刷*(subRowObj)介绍: (id)的[0] = 打印SubRowObjectKey的描述:

Also there is this: Printing description of *(subRowObj): (id) [0] = Printing description of SubRowObjectKey:

这似乎是伟大的工作在32位模式,但一些如何在64位,似乎失去它在哪里。在这里,下面是其中code我在看的部分。

It seems to be working great in 32bit mode but some how in 64bit it seems to loose where it is. Here below is the section of the code I am looking at.

#pragma mark - NSIndexPath (SKSTableView)
static void *SubRowObjectKey;
@implementation NSIndexPath (SKSTableView)
@dynamic subRow;
- (NSInteger)subRow
{
    id subRowObj = objc_getAssociatedObject(self, SubRowObjectKey);
    return [subRowObj integerValue];
}
- (void)setSubRow:(NSInteger)subRow
{
    if (IsEmpty(@(subRow))) {
        return;
    }
    id subRowObj = @(subRow);
    objc_setAssociatedObject(self, SubRowObjectKey, subRowObj, OBJC_ASSOCIATION_ASSIGN);
}
+ (NSIndexPath *)indexPathForSubRow:(NSInteger)subrow inRow:(NSInteger)row inSection:(NSInteger)section
{
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
    indexPath.subRow = subrow;   
    return indexPath;
}

您可以下载并使用code在这里打球: https://github.com/sakkaras/SKSTableView

You can download and play with the code here: https://github.com/sakkaras/SKSTableView

推荐答案

看来, objc_setAssociatedObject()不以标记指针工作。 标记指针是特殊的指针没有的的东西,但价值 被存储在(部分比特)的指针本身。 请参阅在Objective-C ,其中有详细信息的链接例如标记指针。

It seems that objc_setAssociatedObject() does not work with "tagged pointers". Tagged pointers are special pointers that do not point to something, but the "value" is stored in (some bits of) the pointer itself. See for example Tagged pointers in Objective-C, which has links to more information.

标记指针均采用64位code只,如与索引路径 小排和节号,或少量对象。

Tagged pointers are used with 64-bit code only, e.g. for index paths with small row and section numbers, or small number objects.

有可以容易地证实 在标记指针崩溃,并EXC_BAD_ACCESS设置相关的对象 在iOS六十四分之七位:

It can easily be verified that setting an associated object on a tagged pointer crashes with EXC_BAD_ACCESS on iOS 7/64-bit:

static void *key = &key;

id obj = [NSIndexPath indexPathForRow:1 inSection:1];
objc_setAssociatedObject(obj, key, @"345", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
// --> EXC_BAD_ACCESS_(code=EXC_I386_GPFLT) 

同样的情况,以

The same happens with

id obj = @1;
id obj = [NSDate dateWithTimeIntervalSinceReferenceDate:0];

其也以64位模式标记指针。

which are also tagged pointers in 64-bit mode.

我找不到这个限制的任何文件,并会认为这是一个 臭虫的iOS。这里的一个类似的问题报告:<一href="https://github.com/EmbeddedSources/iAsync/issues/22">https://github.com/EmbeddedSources/iAsync/issues/22.我觉得这是值得的bug 报告给苹果。

I could not find any documentation of this restriction and would consider this a bug in iOS. A similar problem was reported here: https://github.com/EmbeddedSources/iAsync/issues/22. I think this is worth a bug report to Apple.

(备注:该问题不会出现在OS X / 64位)

(Remark: The problem does not occur on OS X/64-bit.)

更新(可能的解决方案/解决方法):的该SKSTableView项目(在问题的最后链接)使用类别上 NSIndexPath 和相关对象到第三个属性子行添加到索引路径。 该子行设置暂时

Update (possible solution/workaround): The "SKSTableView" project (link at the end of the question) uses a category on NSIndexPath and associated objects to add a third property "subrow" to an index path. This subrow is set temporarily in

tableView:cellForRowAtIndexPath:

SKSTableView 到现在的子行传递给

of SKSTableView to pass the current subrow to the

tableView:cellForSubRowAtIndexPath:indexPath

的ViewController 类委托方法。

如果你用正确的三级指标的路径相反, 关联对象是没有必要的示例应用程序运行在64位模式下为好。

If you use "proper" three-level index paths instead, the associated object is not needed and the sample app runs in 64-bit mode as well.

我做了如下修改示例项目:

I made the following changes to the sample project:

SKSTableView.m

+ (NSIndexPath *)indexPathForSubRow:(NSInteger)subrow inRow:(NSInteger)row inSection:(NSInteger)section
{
    // Change:
    //NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
    //indexPath.subRow = subrow;
    // To:
    NSUInteger indexes[] = { section, row, subrow };
    NSIndexPath *indexPath = [NSIndexPath indexPathWithIndexes:indexes length:3];

    return indexPath;
}

属性访问方法

The property accessor methods

- (NSInteger)subRow;
- (void)setSubRow:(NSInteger)subRow;

不再需要的

ViewController.m

- (UITableViewCell *)tableView:(UITableView *)tableView cellForSubRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"UITableViewCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (!cell)
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

    // Change:
    //cell.textLabel.text = [NSString stringWithFormat:@"%@", self.contents[indexPath.section][indexPath.row][indexPath.subRow]];
    // To:
    cell.textLabel.text = [NSString stringWithFormat:@"%@", self.contents[[indexPath indexAtPosition:0]][[indexPath indexAtPosition:1]][[indexPath indexAtPosition:2]]];

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    return cell;
}

这篇关于在64位模式objc_setAssociatedObject功能错误不是在32位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆