【问题标题】:What does the 'class' function mean in Objective-C?Objective-C 中的“类”函数是什么意思?
【发布时间】:2015-07-01 14:55:53
【问题描述】:
@interface Soka : NSObject
@property (nonatomic, copy) NSString * name;
-(void)speak;
@end

@implementation Soka
-(void)speak{
    NSLog(@"my name is: %@", self.name);
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSString * asdfasdfasdfsdf = @"xxxxxxx4";
        id cls = [Soka class];
        void * obj = &cls;
        [(__bridge id)obj speak];
    }
    return 0;
}

输出是:

[14402:5468392] my name is: xxxxxxx4

谁能解释一下??

asdfasdfasdfsdf 值是如何设置为类属性的?

谢谢


感谢大家的回复:

进行更新: @Leo

感谢您的回复。

1#Soka Class object cls是什么意思,它的内存结构是什么。它的指针指向什么地址?

2# 找到ocObj对象附近的内存?如果最近的内存是整数值怎么办?它是 OBJC 还是其他理论的一部分?

【问题讨论】:

  • @CoryKramer 不,它是 xcode 中的 objectC。
  • 我看不到该代码如何产生该输出。没有创建实例,也没有初始化name
  • @zaph 好的,所以它使用堆栈来布局Soka 的假实例。有趣,但不是很有帮助。

标签: objective-c


【解决方案1】:

嗯,这有点棘手,没用。它是关于 Objective C 实例内存的

你的代码可以转换成这个

    NSString * asdfasdfasdfsdf = @"xxxxxxx4";
    Class cls = [Soka class]; 
    void * obj = &cls; 
    id ocObj = (__bridge id)obj;
    NSLog(@"%@",[ocObj name]);

让我们一一说清楚

  1. cls 是一个 Soka Class 对象

    Class cls = [Soka class];  
    
  2. obj是指向Soka Class对象的指针

    void * obj = &cls;
    
  3. 这会将 obj 转换为 Object C 对象

    id ocObj = (__bridge id)obj;
    
  4. 当调用这个[ocObj name]时,Objective C会在ocObj对象附近找到内存。它在堆栈中是@"xxxxxxx4"

另外,我对此进行测试以确保我是对的

@interface Soka : NSObject
@property (nonatomic, copy) NSString * name;
@property (nonatomic,copy) NSString * address;
-(void)speak;
@end

@implementation Soka
-(void)speak{
    NSLog(@"my name is: %@", self.name);
}
@end

int main(int argc, char * argv[]) {
@autoreleasepool {
    NSString * asdfasdfasdfsdf = @"xxxxxxx4";
    NSString * address = @"address";
    Class cls = [Soka class];
    void * obj = &cls;
    id ocObj = (__bridge id)obj;
    NSLog(@"%@",[ocObj name]);
    NSLog(@"%@",[ocObj address]);
    return UIApplicationMain(argc, argv, nil,    NSStringFromClass([AppDelegate class]));
    }
 }

这将记录

2015-07-01 23:26:56.857 OCTest[10910:347815] address
2015-07-01 23:26:56.859 OCTest[10910:347815] xxxxxxx4

更新:

+class函数将返回一个类的类对象,类型为Class

那么,Class 类型是什么,它与目标 c 运行时有关

typedef struct objc_class *Class;

这是objc_class的定义

struct objc_class {
Class isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
Class super_class                                        OBJC2_UNAVAILABLE;
const char *name                                         OBJC2_UNAVAILABLE;
long version                                             OBJC2_UNAVAILABLE;
long info                                                OBJC2_UNAVAILABLE;
long instance_size                                       OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;
struct objc_cache *cache                                 OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;

当你创建一个 Objective C 对象时,它会自动管理内存。在您的代码中,使 Objective C 对象像内存一样只是一个技巧。

【讨论】:

  • 感谢您的回复。 1# Soka Class object cls是什么意思,它的内存结构是什么。它的指针指向什么地址? 2#找到ocObj对象附近的内存?如果最近的内存是整数值怎么办?这是 OBJC 还是其他理论的一部分?
  • Class 是目标 C 中的一种类型。请稍等,我将更新我的答案以使其清楚
  • +class函数会返回一个类的类对象,类型为Class,那么cls指向哪里呢?新的锁定记忆?
  • [Soka class],在您的代码中,这将在堆栈中创建一个新内存。 cls 指向这个区域
【解决方案2】:

实际上objective-c 的类是具有属性的结构。 对于您的班级Soka,您在该结构中具有隐藏字段:_nameclass。它们的放置顺序与您的变量 asdfasdfasdfsdfcls 的放置顺序相同。

一切正常,因为在地址&cls 放置了Class 类型的变量,它描述了类。因此,在将obj 转换为id 运行时找到所需字段后,该字段描述了类并信任该指针指向Soka。当然它是错误的,但是在以相同顺序和正确位置放置的变量的情况下,此代码可以正常工作并且不会崩溃。

您不能在堆栈中分配objective-c 对象,如果您认为可以以这种方式分配objective-c 对象,则应避免使用此代码。因为它可能导致无法预料的错误。

【讨论】:

    【解决方案3】:

    class 方法为您提供对象的类型。

    例如,如果您想知道myObject 是否为NSString,您可以这样做:

    [myObject isKindOfClass:[NSString class]]
    

    isKindOfClass 将类型作为其参数,因此我们在 NSString 上调用 class 以获取类型。

    就像 C 语言中的typeof

    【讨论】:

    • 投反对票。在这个问题的背景下,您的回答毫无意义。虽然作者应该给它一个更好的标题。
    猜你喜欢
    • 1970-01-01
    • 2014-01-31
    • 2014-01-17
    • 2011-02-16
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-01
    相关资源
    最近更新 更多