首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSString范畴中的扩展属性崩溃

问NSString范畴中的扩展属性崩溃
EN

Stack Overflow用户
提问于 2015-05-25 05:51:55
回答 3查看 840关注 0票数 3

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

代码语言:javascript
复制
#import "NSString+Name.h"

@interface NSString(Name)

@property (nonatomic, retain) NSString *var;

@end

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

代码语言:javascript
复制
@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 to 710:14433*终止应用程序由于未识别异常'NSInvalidArgumentException',原因:‘__NSCFConstantString setVar::未识别的选择器发送到实例0x1023641c8’

如果我能够在该变量中赋值,那么为什么它说的是不可识别的选择器?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-05-25 07:05:47

你想做什么有几个问题。

  1. 您不能常规地向类别中添加属性。

来自Apple与目标C文档的编程:

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

类别可以添加称为关联对象的内容,但其主要目的是添加方法。

  1. 类别实例方法中的Self引用实例变量

类别实例方法(以a-开头)对调用该方法的实例变量进行操作。在实例方法中,self引用调用方实例变量,而不是类(或类别属性,正如您试图访问的那样)。

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

代码语言:javascript
复制
NSString *myString = @"foo";
[myString newString];

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

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

  1. 方法从新开始对ARC有特殊意义。

另一个问题是,你已经开始了‘新’的方法。对于Objective有一些特定的命名约定与内存管理策略有关。使用alloc、new、copy或mutableCopy启动方法隐式地告诉ARC您的方法(已经创建并)返回了保留的对象。您的newString方法没有创建对象。

票数 2
EN

Stack Overflow用户

发布于 2015-05-25 06:59:33

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

.h

代码语言:javascript
复制
@interface NSString (Name)

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

.m

代码语言:javascript
复制
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);
}

参考这里,这里和这里

票数 5
EN

Stack Overflow用户

发布于 2015-05-25 05:56:24

use _而不是self,它将进入无限循环

代码语言:javascript
复制
- (NSString*)newString
{

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

    return (self.var);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30431977

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档