NSString 类别中的扩展 属性 崩溃

Extension Property Crashes In NSString Category

我刚刚在 Category class

中为 NSString class 创建了一个 Extension
#import "NSString+Name.h"

@interface NSString(Name)

@property (nonatomic, retain) NSString *var;

@end

但是当我试图访问类别 class 中的那个私有变量时,应用程序崩溃并给出错误。

@implementation NSString (Name)

- (NSString*)newString{

    [self setVar:@"Its a new string"];    // Crashes here

    NSLog(@"name = %@",self.var);

    return self.var;
}

@end

崩溃原因

unrecognized selector sent to instance 0x1023641c8 2015-05-25 11:12:49.246 Tute[710:14433] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFConstantString setVar:]: unrecognized selector sent to instance 0x1023641c8'

如果我能够在那个变量中赋值那么为什么它说无法识别的选择器

使用 _ 而不是 self 它将进入无限循环

- (NSString*)newString
{

    _var = @"Its a new string";
    NSLog(@"name = %@",_var);

    return (self.var);
}

您应该使用关联对象。在下面找到对我有用的代码:

.h

@interface NSString (Name)

@property (nonatomic, assign)NSString *var;
- (NSString*)newString;
@end

.m

static char const * const Key = "SomeKey";

@implementation NSString (Name)

- (NSString*)newString
{
    self.var = @"Its a new string";
    NSLog(@"name = %@",self.var);

    return (self.var);
}

- (void)setVar:(NSString *)aVar {
    objc_setAssociatedObject(self, Key, aVar, OBJC_ASSOCIATION_ASSIGN);
}

- (NSString*)var {
    return (NSString*)objc_getAssociatedObject(self, Key);
}

参考here, here and here

您尝试执行的操作存在一些问题。

  1. 您不能按照惯例向类别添加属性。

来自 Apple 的 [Programming with Objective C][1] 文档:

Categories can be used to declare either instance methods or class methods but are not usually suitable for declaring additional properties.

类别可以添加一个叫做关联对象的东西,但它的主要目的是添加方法。

  1. 类内实例方法自身引用实例变量

类别实例方法(以 - 开头的方法)对调用该方法的实例变量进行操作。在实例方法中,self 指的是调用者实例变量,而不是 class(或类别 属性,因为您试图访问)。

在您的类别示例中,您将从现有的 NSString 调用 newString,如下所示:

NSString *myString = @"foo";
[myString newString];

换句话说,newString 类别扩展对调用它的字符串进行操作。您可以更改该字符串,或 return 不同的结果,但问题是您正在对没有此类 var 属性 或方法的 NSString 进行操作。

这就是您看到 'No such selector message,' 的原因,因为 NSString 对您碰巧添加到类别中的不相关 属性 一无所知。

  1. 以 new 开头的方法对 ARC 具有特定含义。

另一个问题是,您已使用 'new' 开始该方法。 Objective-C 有一些与内存管理策略有关的特定命名约定。使用 alloc、new、copy 或 mutableCopy 启动一个方法隐含地告诉 ARC 你的方法(已经创建并且)正在 returning 一个保留的对象。您的 newString 方法没有创建对象。