扩展属性在NSString类别中崩溃

时间:2015-05-25 05:51:55

标签: ios objective-c iphone nsstring

我刚刚在Extension类中为NSString类创建了Category

#import "NSString+Name.h"

@interface NSString(Name)

@property (nonatomic, retain) NSString *var;

@end

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

@implementation NSString (Name)

- (NSString*)newString{

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

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

    return self.var;
}

@end

崩溃原因

  

无法识别的选择器发送到实例0x1023641c8 2015-05-25   11:12:49.246 Tute [710:14433] ***由于未被捕获而终止应用程序   异常'NSInvalidArgumentException',原因:   ' - [__ NSCFConstantString setVar:]:发送到无法识别的选择器   实例0x1023641c8'

如果我能够在该变量中分配值,那么为什么它会说无法识别的选择器

3 个答案:

答案 0 :(得分:5)

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

·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);
}

参考hereherehere

答案 1 :(得分:2)

您尝试做的事情存在一些问题。

  1. 您不能按常规方式向属性添加属性。
  2. 来自Apple的[使用Objective C编程] [1]文档:

      

    类别可用于声明实例方法或类方法,但通常不适用于声明其他属性。

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

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

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

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

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

      这就是为什么你看到'没有这样的选择器消息',因为NSString对你碰巧添加到你的类别中的无关属性一无所知。

      1. 以new开头的方法对ARC具有特定含义。
      2. 另一个问题是,你已经用'new'开始了这个方法。 Objective-C有一些与内存管理策略有关的特定命名约定。使用alloc,new,copy或mutableCopy启动方法会隐式告诉ARC您的方法(已创建和)正在返回一个保留对象。您的newString方法未创建对象。

答案 2 :(得分:1)

使用_代替self,它将进入无限循环

- (NSString*)newString
{

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

    return (self.var);
}
相关问题