【问题标题】:Why in Objective-C and iOS, [[NSMutableArray alloc] init] gave warning but NSMutableArray.new didn't?为什么在 Objective-C 和 iOS 中,[[NSMutableArray alloc] init] 给出警告但 NSMutableArray.new 没有?
【发布时间】:2012-04-22 04:02:06
【问题描述】:

我的MainView 类有一个属性arr

@property NSMutableArray *arr;

在我的ViewController.m 中,在viewDidLoad 中,如果我使用的话

MainView *mainView = (MainView *) self.view;
mainView.arr = [[NSMutableArray alloc] init];

它已编译,但给出了“将保留的对象分配给不安全的属性;对象将在分配后释放”的警告。但是如果我将上面的第二行更改为

mainView.arr = NSMutableArray.new;    

那么不会有警告。我以为alloc initnew 一样?为什么第一个版本会给出警告,实际上它是危险的还是可以做到没有警告?

【问题讨论】:

  • 这是什么版本的 Xcode?​​span>
  • Xcode 4.3.2.. 当前版本

标签: objective-c ios


【解决方案1】:

如果您使用[NSMutableArray new] 语法,您将看到警告,因此您的问题消失并不是问题,而是您的NSMutableArray.new 的非标准语法没有生成警告。问题是您的属性默认为 unsafe_unretained,每当您将保留对象分配给 unsafe_unretained 对象时,ARC 都会立即为您释放它。只需尝试将一个对象添加到您的数组,然后 NSLog'ing 它,您就会看到说明问题的 EXC_BAD_ACCESS。将您的属性更改为:

@property (strong, nonatomic) NSMutableArray *arr;

你的问题就消失了。

同样,您对NSMutableArray.new 的非标准使用没有警告并不表示没有问题,而是编译器没有为您生成警告。 (坦率地说,我真的很惊讶用于调用方法的点语法完全有效。点表示法通常用于访问属性,而不是用于调用方法。)如果你真的想使用 [NSMutableArray new] 语法,请使用 @987654326 @。但首选语法实际上是[[NSMutableArray alloc] init]

注意警告。

【讨论】:

  • 很有趣...即使有警告,我也可以毫无问题地访问数组并将对象添加到数组中...可以在 3 分钟后将对象添加到数组中并且它是还可以……
  • 您在使用 ARC 吗?我描述的行为与 ARC 代码有关。如果没有,您将需要使用@Nikolai 的保留语法,它消除了警告。但无论如何,您不希望留下没有属性的代码。
  • 在我的 ARC 项目中,我能够向数组中添加一个字符串,但是当我执行 NSLog(@"%@", mainView.arr) 时,我得到了 EXC_BAD_ACCESS。
  • 使用 ARC 很棒。 (我永远不会回去!)我不知道为什么你没有看到我描述的行为,但无论如何,如果你的对象拥有,你真的想声明它是强大的,以防止出现我描述的那种问题的可能性。编译器的警告是完全正确的。
【解决方案2】:

您必须说明财产的类型。例如:

@property (retain) NSMutableArray *arr;

请参阅文档中的属性类型

【讨论】:

  • (strong, nonatomic)(retain) 都使警告消失,程序运行良好...我只是不知道哪个版本更标准或更常用?
  • ARC 使用 strong,非 ARC 保留。
  • 非原子性更快。在 iOS 上使用(强,非原子),在 mac 上(保留)。
  • @NikolaiNagorny,非原子更快,所以你说使用它是正确的,但如果涉及线程,请使用原子。但是如果使用 ARC,则应该使用 strong,如果不使用,则保留。这与 iOS/Mac 无关。
【解决方案3】:

我认为您收到警告的原因是 arr 不是强参考。如果您尝试“@property (strong, nonatomic) NSMutableArray *arr;”,警告将会消失。

附: “(强,非原子)”是采用自动引用计数(ARC)时使用的方法。我也很惊讶 NSMutableArray.new 起作用了。我认为最好使用“[[NSMutableArray alloc] init]”。这样,Xcode 会告诉你正在实例化的类是否有更合适的特殊初始化器(例如“initWithFrame:”)。

【讨论】:

  • (strong, nonatomic)(retain) 都使警告消失,程序运行良好...我只是不知道哪个版本更标准或更常用?
  • +new 被记录为与 +alloc/-init 执行相同的操作,因此缺少编译器警告是错误。
猜你喜欢
  • 1970-01-01
  • 2012-01-23
  • 2013-02-21
  • 1970-01-01
  • 2016-02-16
  • 1970-01-01
  • 2014-01-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多