- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
对于所有进入 Objective-c 内部的人来说,这是一个非常有趣的问题......
所以... NSObject
为对象和类返回相同的 copy
实现(如我所料)。但是,NSArray
和 NSMutableArray
不仅返回对象和类的 objectAtIndex:
的不同实现,而且每个对象都有不同的实现。
有谁知道为什么下面的代码会产生这样的行为?...(至少 NSArray
和 NSMutableArray
的类实现是相同的:))
NSObject *obj = [[[NSObject alloc] init] autorelease];
NSLog(@"NSObject instance %@", [NSValue valueWithPointer:method_getImplementation(class_getInstanceMethod(object_getClass(obj), @selector(copy)))]);
NSLog(@"NSObject class %@", [NSValue valueWithPointer:method_getImplementation(class_getInstanceMethod([NSObject class], @selector(copy)))]);
NSArray *array = [[[NSArray alloc] init] autorelease];
NSLog(@"NSArray instance %@", [NSValue valueWithPointer:method_getImplementation(class_getInstanceMethod(object_getClass(array), @selector(objectAtIndex:)))]);
NSLog(@"NSArray class %@", [NSValue valueWithPointer:method_getImplementation(class_getInstanceMethod([NSArray class], @selector(objectAtIndex:)))]);
NSMutableArray *array1 = [[[NSMutableArray alloc] init] autorelease];
NSLog(@"NSMutableArray instance %@", [NSValue valueWithPointer:method_getImplementation(class_getInstanceMethod(object_getClass(array1), @selector(objectAtIndex:)))]);
NSLog(@"NSMutableArray class %@", [NSValue valueWithPointer:method_getImplementation(class_getInstanceMethod([NSMutableArray class], @selector(objectAtIndex:)))]);
日志
2012-11-06 16:35:22.918 otest[71367:303] NSObject instance <c0fa7200>
2012-11-06 16:35:23.757 otest[71367:303] NSObject class <c0fa7200>
2012-11-06 16:35:30.348 otest[71367:303] NSArray instance <809a9b00>
2012-11-06 16:35:31.121 otest[71367:303] NSArray class <70bfa700>
2012-11-06 16:35:33.854 otest[71367:303] NSMutableArray instance <f05f9a00>
2012-11-06 16:35:34.824 otest[71367:303] NSMutableArray class <70bfa700>
最佳答案
实现细节,全部。因此,这是一个相对见多识广的猜想。
首先,无需跳过这样的环来打印十六进制值,只需执行以下操作:
NSLog(@"imp: %p", [NSObject instanceMethodForSelector:@selector(...)]);
请注意,在类对象上调用 methodForSelector:
会返回类方法的 IMP。
现在,回到手头的问题。
Objective-C 与其他流行的 OO 语言(但不是全部)的区别在于,Class 对象实际上是 Metaclass 的实例。那个元类——除了“元类”之外没有真正的名称——恰好响应 NSObject
协议(protocol)(或多或少)。事实上,它有点像 NSObject
的派生物。
因此,当您在实例和类的 NSObject
上获得某些选择器的实现时,它们通常是相同的。请注意,这是允许类成为 NSDictionary 中的键的原因;类可以复制。 NSObject
的 copy
方法只是 return [self retain];
并且,当然,retain
在一个类上是空操作,因为它们 [几乎总是] 作为单例静态编译到二进制文件中。好吧,从技术上讲,copy
调用 copyWithZone:
确实 return [self retain];
(这就是为什么你必须子类化 copyWithZone:
即使区域已被弃用)。
现在,正如 Hot Licks 指出的那样,NS*Array
是一个类集群,其内部实现细节在最近几个版本中发生了变化。过去,所有实例都桥接到配置不同的 NSCFArray
。在最近的版本中,您将看到(原文如此)__NSArrayI
和 __NSArrayM
实例,它们对应于不可变和可变实例。大多数情况下 - 发生的事情远不止于此,但这是非常典型的。
objectAtIndex:
的实例方法在两个类之间是不同的,这是典型的类集群。集群的要点是提供一个原始接口(interface),其中包含一堆根据该原始接口(interface)实现的方法(这就是为什么 header 分为核心 @interface
和一系列分类 @interfaces
;基类中的类别完全根据核心 API 实现。
在内部,集群中有公开声明的类的具体子类。这些具体的子类针对特定任务进行了高度优化——在这种情况下是不可变与可变数组存储(但可能有更多非公共(public)子类针对不同目的进行了优化)——其中子类覆盖了广告 API 以提供高度各种方法的优化版本。
因此,您在这两个类中看到的是针对可变与不可变情况优化的 objectAtIndex:
的不同实现。
现在,为什么类方法相同?好问题。让我们尝试调用它:
((void(*)(id,SEL,int))[[NSArray class] methodForSelector: @selector(objectAtIndex:)])([NSArray class], @selector(objectAtIndex:), 0);
2012-11-06 09:18:23.842 asdfasdf[17773:303] *** Terminating app due to uncaught
exception 'NSInvalidArgumentException', reason: '+[NSArray objectAtIndex:]:
unrecognized selector sent to class 0x7fff7563b1d0'
啊哈!因此,您要求实现一种方法,该方法在调用时会出现“无法识别此方法”异常。事实上:
NSLog(@"%@",
[NSArray class] respondsToSelector:@selector(objectAtIndex:)] ? @"YES" : @"NO");
2012-11-06 09:24:31.698 asdfasdf[17839:303] NO
看起来运行时正在返回一个 IMP,它会吐出一个很好的错误,表明您尝试——通过迂回方式——使用目标对象(在本例中为元类实例)不响应的选择器至。这就是为什么 instanceMethodForSelector:
的文档声明您应该先使用 respondsToSelector:
以防目标是否实现选择器存在疑问。
(好吧,这变成了比预期更多的书......希望仍然有用!)
关于iphone - NSArray 和 NSMutableArray 的 Objective-c 内部机制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13255572/
在我的应用程序中,我必须创建这样的结构: $arrProducts = array( array( “product_id” => “1”, “qty” =>
我相信我的问题涉及指针,这是一个我经常纠结的概念,但这就是我正在尝试做的事情。 我有六个 NSArray。我想要一个由这六个数组组成的额外 NSArray,所以: self.arr1 = [NSArr
我正在使用 VKSdk 制作 iOS 应用程序.我想将数据从 response.json[@"items"](它是 nsarray,response.json 是它的 nsdictionary)复制到
我创建 NSArray *test = @[@[@1,@2,@3,@4], @[@3,@5,@6,@7]]; 这将被视为 nsarray 的 nsarray。 但是当我想用打印出来的时候 NSLog
首先引用下图: 我有一个包含 9 个元素的 NSArray。这 9 个元素中的每一个都包含另外 5 个元素。 我想做的是将 [*][1] 从每个地方带到另一个地方,只包含这些日期。 如何最好地实现这一
我正在尝试将 NSDictionaries 数组排序为基于 NSDictionary valueForKey: 第一个字母之一的字母化数组数组 实际上我想要看起来有点像这样的东西 Array A //
我有一个 NSArray 输出如下: ( { category = 1; categoryname = Random; excuse = "Enter your exc
我是 Objective-C 和 iPhone 的新手 我必须使用值对 NSDictionary 进行排序,并且根据我必须排列该值的键,我已经对数组进行了排序。 //getting values NS
我觉得这很简单,但我就是无法理解它。我有一组星期几供用户选择: NSArray * daysOfTheWeek = [NSArray arrayWithObjects:@"sunday", @"mon
我有一个 NSArray 对象: class Object { var name: String? = nil var id: String? = nil } 我想创建一个具有唯一“名
我只是想将 NSNumbers 的 NSArray 排序为数字顺序,但我不确定最好的方法。以我的思维方式,001 和 002 具有相当的可比性,所以我怀疑两者都可以。对于 003,我不确定当方法需要
我面临一个非常常见的场景。 我有一个 NSArray,它有一个自定义类型的对象,比如 Person。 Person 类具有以下属性:firstName、lastName 和 age。 如何从具有 Pe
我有一个 NSArray,其中填充了大约 30 个 NSDate 格式的日期, 我需要做的是从中创建另一个数组,其中包含从第一个日期到最后一个日期的所有日期的 bool 值。 前数组 111/1/12
NSarray 的简单问题。我将对象存储在 NSMuteableArray 中。[obj1, obj2, obj3] 如果选择了一个对象,我想把它放在数组的前面。 IE。如果选择了 obj3,则: [
我已按字母顺序存储联系人,因此我有联系人列表的数组数组,该数组已显示在屏幕上。现在我想通过姓名搜索联系人,但谓词在这里无法正常工作。我已经完成了下面的代码。 filterArray.filter
对于使用 ARC 的 iOS 5.0 应用程序,我有一个对象的 NSArray,其中包含其他对象的 NSArray。是否可以在不遍历数组的情况下从内部数组中提取对象列表,例如比如,使用 NSPredi
这个问题在这里已经有了答案: Sort NSArray of custom objects based on sorting of another NSArray of strings (5 个答案
我有一个 NSArray 对象,每个对象都包含一个“键”字段 我有另一个带有嵌套NSArrays的NSArray,通过不同的字段“按字段分组”对这些对象进行分组,例如显示名称(字母分组) 例如 @in
我正在尝试在多个 NSArray 中搜索和合并对象。 基本上 NSArray 具有多个 NSArray 和 1 个对象,然后是 NSDictionary。我想检查该对象是否已经存在并将其与现有对象合并
这个问题在这里已经有了答案: Check that the contents of one NSArray are all in another array (9 个回答) 关闭 8 年前。
我是一名优秀的程序员,十分优秀!