【问题标题】:how can I look up objective-c's property @synthesize getter setter code我如何查找objective-c的属性@synthesize getter setter代码
【发布时间】:2017-12-07 07:59:42
【问题描述】:

在面试中有一个问题“NSMutableArray 属性是否可以使用复制,为什么不使用”我已经搜索了答案,但我想看看自动生成的 getter setter 代码我该怎么做?

【问题讨论】:

  • copy 返回一个不可变的NSArraymutableCopy 将返回一个复制的 NSMutableArray。通过将属性声明为copy,您可以访问元素,但如果不显式调用setter,您将无法改变内部结构。基本上这就是我们拥有copy 属性的确切原因。从技术上讲,所有NSMutableArray 属性都应该是copy,除非你的设计不好。

标签: ios objective-c memory-management


【解决方案1】:

你看不到 setter 的 Obj-C 代码,只有汇编器。为此,首先在 Xcode 中选择包含该属性的源文件,然后选择菜单项 Produce > Perform Action > Assemble "File.m"。这将打开一个包含汇编代码的窗口。搜索 setPropertyName:,其中 PropertyName 是您的资产的大写名称。

这将显示 setter 调用 _objc_setProperty_nonatomic_copy_objc_setProperty_atomic_copy。要查看这些代码,您需要使用调试器并单步执行。他们基本上只是打电话给copyWithZone:

更重要的是面试问题背后的原因。无论是简单的实验,还是通过上面的汇编程序进行挖掘,都表明copy 属性属性始终执行copy 而不是mutableCopy。所以声明:

@property (nonatomic, copy) NSMutableArray *shouldBeInvalid;

在理想情况下会产生编译器错误。如果为属性分配一个可变数组值:

self.shouldBeInvalid = @[ @24 ].mutableCopy;

那么由于copy,实际分配的值是一个不可变数组(NSArray),与NSMutableArray声明的类型相矛盾。稍后尝试将属性值用作可变数组:

[self.shouldBeInvalid addObject:@42];

将产生运行时错误,因为属性的值是与其声明类型相反的不可变对象...

您还会发现编译器很高兴地允许您将不可变数组分配给属性:

self.shouldBeInvalid = @[ @24 ];

没有任何警告。

面试官可能想要你解释的是,对于属性copy + 可变类型在 Objective-C 中没有意义,因为副本会产生不可变的对象值。但是,具有copy 和不可变对象类型(NSArrayNSDictionary 等)的属性确实有意义,因此如果为可变对象值分配了它的不可变副本,则会生成它的不可变副本,从而防止属性值发生变化出乎意料,例如:

@property (nonatomic) NSArray *shouldHaveCopy;

NSMutableArray *sample = @[ @"oops" ].mutableCopy;

self.shouldHaveCopy = sample;

[sample addObject:@"'immutable' property changed"];

// self.shouldHaveCopy now references a two element array despite
// its type being `NSArray` 

所以一般规则是:

  • 旨在具有可变对象值的属性 (NSMutableDictionary et al) 永远不应指定 copy;和
  • 当存在对应的可变对象子类时(例如,NSArray 具有 NSMutableArray 等),旨在具有不可变对象值的属性应始终指定 copy

HTH

【讨论】:

  • 当我执行这个“Produce > perform Action > Assemble file.m”然后Xcode崩溃过程:Xcode [6985]路径:/Applications/Xcode.app/Contents/MacOS/Xcode Identifier:com。 apple.dt.Xcode 版本:9.0 (13247) 构建信息:IDEFrameworks-13247000000000000~26 代码类型:X86-64 (Native) 父进程:??? [1] 负责人:Xcode [6985] 用户 ID:501 日期/时间:2017-12-08 20:08:52.685 +0800 操作系统版本:Mac OS X 10.12.6 (16G1108) 报告版本:12
  • Xcode 崩溃并不好,虽然它偶尔会发生 :-( 你应该有机会向 Apple 提交报告,你应该接受。重新启动 Xcode 后问题通常会消失。如果它在特定项目上持续存在按住选项键然后选择Project > Clean Build Folder 以查看是否可以修复它。HTH
  • @CRD 你的解释是完全有效的,但是NSObjectmutableCopy(以及copy)方法没有被定义为属性。使用.syntax 调用它们表明相反。
  • @Kamil.S - 同意,但这是“坏”还是“个人品味”的问题?缺点是什么?
  • @CRD 我的理由是我们在代码中的任何地方都看不到NSObject.alloc.init,因为即使编译器不会抱怨并且从技术上讲它可以工作,这些方法也不是属性。所以恕我直言,首选的方法是坚持原始定义。如果某些东西被定义为属性,那么.syntax 是一种方法,否则就不是真的。
【解决方案2】:

你看不到源代码。不过,您可以在 Xcode 的调试器中进入它,并查看它的汇编版本,如果您知道任何平台的汇编程序或擅长猜测英文单词的缩写,那么它是相当可读的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多