我刚刚在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'
如果我能够在该变量中分配值,那么为什么它会说无法识别的选择器
答案 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);
}
答案 1 :(得分:2)
您尝试做的事情存在一些问题。
来自Apple的[使用Objective C编程] [1]文档:
类别可用于声明实例方法或类方法,但通常不适用于声明其他属性。
一个类别可以添加一个称为关联对象的东西,但其主要目的是添加方法。
类别实例方法(以 - 开头的方法)对调用该方法的实例变量进行操作。在实例方法中,self引用调用者实例变量,而不是您尝试访问的类(或类别属性)。
在您的类别示例中,您将从现有的NSString调用newString,如下所示:
NSString *myString = @"foo";
[myString newString];
换句话说,newString类别扩展对调用它的字符串进行操作。您可以更改该字符串,或返回不同的结果,但问题是您正在使用没有此类var
属性或方法的NSString。
这就是为什么你看到'没有这样的选择器消息',因为NSString对你碰巧添加到你的类别中的无关属性一无所知。
另一个问题是,你已经用'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);
}