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);
}
您尝试执行的操作存在一些问题。
- 您不能按照惯例向类别添加属性。
来自 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.
类别可以添加一个叫做关联对象的东西,但它的主要目的是添加方法。
- 类内实例方法自身引用实例变量
类别实例方法(以 - 开头的方法)对调用该方法的实例变量进行操作。在实例方法中,self 指的是调用者实例变量,而不是 class(或类别 属性,因为您试图访问)。
在您的类别示例中,您将从现有的 NSString 调用 newString,如下所示:
NSString *myString = @"foo";
[myString newString];
换句话说,newString 类别扩展对调用它的字符串进行操作。您可以更改该字符串,或 return 不同的结果,但问题是您正在对没有此类 var
属性 或方法的 NSString 进行操作。
这就是您看到 'No such selector message,' 的原因,因为 NSString 对您碰巧添加到类别中的不相关 属性 一无所知。
- 以 new 开头的方法对 ARC 具有特定含义。
另一个问题是,您已使用 'new' 开始该方法。 Objective-C 有一些与内存管理策略有关的特定命名约定。使用 alloc、new、copy 或 mutableCopy 启动一个方法隐含地告诉 ARC 你的方法(已经创建并且)正在 returning 一个保留的对象。您的 newString
方法没有创建对象。
我刚刚在 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);
}
您尝试执行的操作存在一些问题。
- 您不能按照惯例向类别添加属性。
来自 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.
类别可以添加一个叫做关联对象的东西,但它的主要目的是添加方法。
- 类内实例方法自身引用实例变量
类别实例方法(以 - 开头的方法)对调用该方法的实例变量进行操作。在实例方法中,self 指的是调用者实例变量,而不是 class(或类别 属性,因为您试图访问)。
在您的类别示例中,您将从现有的 NSString 调用 newString,如下所示:
NSString *myString = @"foo";
[myString newString];
换句话说,newString 类别扩展对调用它的字符串进行操作。您可以更改该字符串,或 return 不同的结果,但问题是您正在对没有此类 var
属性 或方法的 NSString 进行操作。
这就是您看到 'No such selector message,' 的原因,因为 NSString 对您碰巧添加到类别中的不相关 属性 一无所知。
- 以 new 开头的方法对 ARC 具有特定含义。
另一个问题是,您已使用 'new' 开始该方法。 Objective-C 有一些与内存管理策略有关的特定命名约定。使用 alloc、new、copy 或 mutableCopy 启动一个方法隐含地告诉 ARC 你的方法(已经创建并且)正在 returning 一个保留的对象。您的 newString
方法没有创建对象。