【问题标题】: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

谁能告诉我发生了什么?

【问题讨论】:

    标签: ios objective-c macos cocoa-touch cocoa


    【解决方案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。我刚刚尝试过,对我来说,它确实引发了异常。
    • 可能是我的粗心大意,也给我丢了。谢谢。