iOS 10 NSNumber与枚举崩溃

问题描述 投票:0回答:1

我有一个非常奇怪的问题,与 NSNumber 对象,并在运行 iOS os 10 版本的设备上访问它们。

在此声明一下--这个问题不会发生在其他iOS os版本上。

我已经声明了一个枚举,就像这样。

typedef NS_ENUM(NSInteger, MYENUM) {
   FIRST = 1500,
   SECOND = 1700,
   THIRD = 1900,
   ...
};

当使用这个枚举时,我是以这种方式传递的。

[[MyObject alloc] initObjectWith:@(FIRST)];

除了内部逻辑,我在字典中使用枚举,因此需要将其转换为NSNumber。

当这样做的时候,应用程序崩溃了,因为这个枚举在某种程度上不是一个NSNumber,而是一个NSIndexPath。

Screenshot

为什么会发生这种情况?

当我删除了方框中的文字,并将方法签名改为接受一个NSInteger时,这种崩溃就消失了。

我试着在网上搜索这种类型的问题,但没有找到。

进一步的解释(根据评论

在myObject的init方法里面没有发生特殊的逻辑,只是分配了定义为 NSNumber 的参数。

关于崩溃日志,Xcode在提供不那么有用的崩溃日志方面是出了名的,我看到的是 EXC_BAD_ACCESS,这可能意味着访问一个已经被释放的对象或潜在的内存泄漏。

MyObject类的定义如下。

头文件:

@interface ISNEvent : NSObject

@property(nonatomic, assign) NSNumber* number;

-(instancetype)initObjectWith:(NSNumber*)number;

@end

.m文件:

- (instancetype)initObjectWith:(NSNumber*)number {
   self = [super init];
   if (self) {
     _number = number;
   }

   return self;
}
enums ios10
1个回答
1
投票

你已经定义了你的属性 assign 内存语义。

@property(nonatomic, assign) NSNumber* number;

这意味着,你会得到一个引用到你提供的任何东西, 但你不会保持一个强大的参考,你不会。nil 当对象被deallocated时,你的引用就会被删除。这是两全其美的事情,因为你对一个允许被deallocated的对象保留了一个悬而未决的引用。正如你所说,这个特殊的错误 "可能......意味着访问一个已经被释放的对象",而这正是这里发生的事情。

你可以考虑暂时打开僵尸 (指挥+<)或 "产品"" "方案"" "编辑方案...",然后进入 "运行 "设置的 "诊断 "部分,看看你的行为是否发生了变化。你可能不会再看到 NSIndexPath (或其他什么)的提法,而是在某种程度上证实了这一点。NSNumber 实例已被重新分配。

无论如何,你无疑是想让这个 NSNumber 财产a strong 参考。

@property(nonatomic, strong) NSNumber *number;

另一个解决办法是使其 weak,允许它被重新分配,但安全地将您的引用设置为 nil. 这比安全 assign但我也怀疑这是不是你的意图。第三种选择是 copy这就是我们有时在可变类型中使用的东西,但在这里并不适用。

一句话,现在,我建议永远不要使用 assign 内存语义与任何对象类型。使用 strong, copyweak. 在这种情况下: strong 是你想要的。只使用 assign 与原始数据类型(如 NSInteger, CGFloat等),但不是对象类型。

而且,记住,当你完成对僵尸的测试后,请关闭该诊断功能。

© www.soinside.com 2019 - 2024. All rights reserved.