基础类的扩展

Posted

技术标签:

【中文标题】基础类的扩展【英文标题】:Extension for a Foundation class 【发布时间】:2013-06-12 09:19:33 【问题描述】:

由于基础类(比如 NSString)的 .m 文件不可用,我在想是否可以在同一类上声明的类别的 .m 文件中声明扩展。我成功地创建了一个内部不使用任何实例变量的私有方法。但是,当我尝试访问在接口内声明的 iVar 时,它会导致问题。 *这没有任何目的,只是在尝试。

我所做的是在NSString 上声明一个类别:

NSString+TestInterface.h

@interface NSString (TestInterface)
@end

NSString+TestInterface.m

@interface NSString () 

    NSString *myVar;

@property (strong) NSString *myVar;
-(void)myPrivateMethod;
@end


@implementation NSString (TestInterface)
-(void)myPrivateMethod
    myVar=@"random";
//    [self setValue:@"check" forKey:@"myVar"];

    NSLog(@"Private %@",myVar);
//    NSLog(@"Private %@",[self valueForKey:@"myVar"]);


@end

当我这样做时,我得到以下编译器错误:

架构 x86_64 的未定义符号: “_OBJC_IVAR_$_NSString.myVar”,引用自: - [NSString(TestInterface) myPrivateMethod] 在 NSSTring+TestInterface.o ld 中:未找到体系结构的符号 x86_64

谁能告诉我发生了什么?

【问题讨论】:

【参考方案1】:

您不能在您不拥有其实现(.m 文件)的外部类的扩展/类别中添加实例变量。

您当然可以添加充当 setter 和 getter 的方法。对于实际值的存储,您可以使用 objc_setAssociatedObject ,它是某种全局存储,您可以将值与键和对象的实例相关联。

这里有很好的解释、讨论和示例:What is objc_setAssociatedObject() and in what cases should it be used?

【讨论】:

谢谢。我不知道objc_setAssociatedMethod。 +1【参考方案2】:

您只能在类的原始主要实现所在的同一翻译单元(文件)中使用类扩展定义新的实例变量。这意味着您无法有效地添加实例变量到你没有源代码的类。

【讨论】:

好的。但是为什么setValue:ForKey: 不会抛出异常而valueForKey: 会呢? @Rakesh IDK。我刚刚尝试过,对我来说,它确实引发了异常。 可能是我的粗心大意,也给我丢了。谢谢。

以上是关于基础类的扩展的主要内容,如果未能解决你的问题,请参考以下文章

适合具备 C 语言基础的 C++ 教程

java基础学习

Python基础-封装与扩展静态方法和类方法

Java——基础知识——类的继承父类的重写Object类final关键字

新年在家学java之基础篇-高级类的特性

Objective-C编程 — 类和继承