OC @属性 块在类别中
OC @property with block in category
对不起。我想使用 block 作为我的 属性 in category 来改变我的代码风格如下,但是有错误,我不知道为什么。
这是我的代码:
```
typedef NSString* (^MethodreplacingRangeWithString)(NSRange range,NSString * string);
typedef NSString* (^MethodAppend)(NSString *) ;
@interface NSString (Speech)
@property(nonatomic ,copy)MethodreplacingRangeWithString replacingRangeWithString ;
@property(nonatomic, copy)MethodAppend append ;
+(void)speech:(NSString *)content;
@end
@implementation NSString (Speech)
//setter and getter
static NSString * a = @"replacingRangeWithString" ;
-(void)setReplacingRangeWithString:(MethodreplacingRangeWithString)replacingRangeWithString{
objc_setAssociatedObject(self, @selector(replacingRangeWithString), replacingRangeWithString, OBJC_ASSOCIATION_RETAIN_NONATOMIC) ;
}
-(MethodreplacingRangeWithString)replacingRangeWithString{
return objc_getAssociatedObject(self, @selector(replacingRangeWithString)) ;
}
//setter and getter
static NSString * b = @"append" ;
-(void)setAppend:(MethodAppend)append{
objc_setAssociatedObject(self, @selector(append), append,OBJC_ASSOCIATION_RETAIN_NONATOMIC) ;
}
-(MethodAppend)append{
return objc_getAssociatedObject(self, @selector(append)) ;
}
//block
-(void)configureReplacingRangeWithStringProperty{
__weak typeof (self) weakSelf = self ;
self.replacingRangeWithString = ^(NSRange range,NSString * str){
return [weakSelf stringByReplacingCharactersInRange:range withString:str];
};
}
-(void)configureAppend{
__weak typeof (self)weakSelf = self ;
self.append = ^(NSString *str){
return [weakSelf stringByAppendingString:str] ;
};
}
to change the style as follows :
NSString * str = @"hello world" ;
[str configureAppend] ;
[str configureReplacingRangeWithStringProperty] ;
str = str.replacingRangeWithString(NSMakeRange(6, 5),@"iOS").append(@" hhhhh") ;
```
我的配置有问题,我不知道为什么
您将属性声明为 copy
,然后实现 strong
setter。
更有可能的是,您的崩溃是因为堆栈上有一个块在堆栈帧被销毁后正在使用。
您遇到的实际崩溃的原因可能是对相关对象的误解。当您将一个对象关联到一个 特定实例 ,而不是所有相同类型的实例。
查看您的代码:
[str configureAppend] ;
[str configureReplacingRangeWithStringProperty] ;
此时您已将两个对象与 str
所指的特定实例相关联。现在你尝试做:
str = str.replacingRangeWithString(NSMakeRange(6, 5),@"iOS").append(@" hhhhh") ;
分解:
str.replacingRangeWithString
这会在 str
引用的任何对象实例上调用 属性 replacingRangeWithString
。我们称该对象为 A。现在您之前的两个语句将对象与 A 相关联,所以这有效并且您可以取回块引用。
str.replacingRangeWithString(NSMakeRange(6, 5),@"iOS")
这会调用块和 return 一个 不同的 字符串,将该对象称为 B。
str.replacingRangeWithString(NSMakeRange(6, 5),@"iOS").append
这会在对象 B 上调用 属性 append
,您没有将任何对象与对象 B 相关联,因此这 return 是一个空引用。
str.replacingRangeWithString(NSMakeRange(6, 5),@"iOS").append(@" ahhhh")
您试图调用您的 "block",但您有一个空引用 => 内存错误。
更新
在这一点上,我最初建议你需要重新考虑你的设计 - 你确实这样做了 - 并且解决方案可能不像你想要的那么简单 - 从那时起我就意识到可能有一个简单的方法...
提供 你只是想用 属性 访问替换方法调用,这样你就可以整齐地将调用链接在一起;也就是说,您无意使用执行不同操作的块调用 configure...
方法;那么您可以在 属性 中动态创建和 return 一个块。这是 append
的大纲。首先将 属性 设为只读:
@property(nonatomic, readonly) MethodAppend append;
然后使用以下方式定义它:
-(MethodAppend)append
{
NSString *copied = self.copy;
return ^(NSString *string){ return [copied stringByAppendingString:string]; };
}
这首先复制字符串,以防调用它的实例是 NSMutableString
,你不知道在调用这个 属性 之后多久会调用该块,并且到那时字符串值可能已经更改。然后它 return 是一个块,它接受所需的参数并调用预期的方法。
这就是所有需要的,没有设置器或配置方法,也没有关联对象。
HTH
对不起。我想使用 block 作为我的 属性 in category 来改变我的代码风格如下,但是有错误,我不知道为什么。
这是我的代码:
```
typedef NSString* (^MethodreplacingRangeWithString)(NSRange range,NSString * string);
typedef NSString* (^MethodAppend)(NSString *) ;
@interface NSString (Speech)
@property(nonatomic ,copy)MethodreplacingRangeWithString replacingRangeWithString ;
@property(nonatomic, copy)MethodAppend append ;
+(void)speech:(NSString *)content;
@end
@implementation NSString (Speech)
//setter and getter
static NSString * a = @"replacingRangeWithString" ;
-(void)setReplacingRangeWithString:(MethodreplacingRangeWithString)replacingRangeWithString{
objc_setAssociatedObject(self, @selector(replacingRangeWithString), replacingRangeWithString, OBJC_ASSOCIATION_RETAIN_NONATOMIC) ;
}
-(MethodreplacingRangeWithString)replacingRangeWithString{
return objc_getAssociatedObject(self, @selector(replacingRangeWithString)) ;
}
//setter and getter
static NSString * b = @"append" ;
-(void)setAppend:(MethodAppend)append{
objc_setAssociatedObject(self, @selector(append), append,OBJC_ASSOCIATION_RETAIN_NONATOMIC) ;
}
-(MethodAppend)append{
return objc_getAssociatedObject(self, @selector(append)) ;
}
//block
-(void)configureReplacingRangeWithStringProperty{
__weak typeof (self) weakSelf = self ;
self.replacingRangeWithString = ^(NSRange range,NSString * str){
return [weakSelf stringByReplacingCharactersInRange:range withString:str];
};
}
-(void)configureAppend{
__weak typeof (self)weakSelf = self ;
self.append = ^(NSString *str){
return [weakSelf stringByAppendingString:str] ;
};
}
to change the style as follows :
NSString * str = @"hello world" ;
[str configureAppend] ;
[str configureReplacingRangeWithStringProperty] ;
str = str.replacingRangeWithString(NSMakeRange(6, 5),@"iOS").append(@" hhhhh") ;
```
我的配置有问题,我不知道为什么
您将属性声明为 copy
,然后实现 strong
setter。
更有可能的是,您的崩溃是因为堆栈上有一个块在堆栈帧被销毁后正在使用。
您遇到的实际崩溃的原因可能是对相关对象的误解。当您将一个对象关联到一个 特定实例 ,而不是所有相同类型的实例。
查看您的代码:
[str configureAppend] ;
[str configureReplacingRangeWithStringProperty] ;
此时您已将两个对象与 str
所指的特定实例相关联。现在你尝试做:
str = str.replacingRangeWithString(NSMakeRange(6, 5),@"iOS").append(@" hhhhh") ;
分解:
str.replacingRangeWithString
这会在 str
引用的任何对象实例上调用 属性 replacingRangeWithString
。我们称该对象为 A。现在您之前的两个语句将对象与 A 相关联,所以这有效并且您可以取回块引用。
str.replacingRangeWithString(NSMakeRange(6, 5),@"iOS")
这会调用块和 return 一个 不同的 字符串,将该对象称为 B。
str.replacingRangeWithString(NSMakeRange(6, 5),@"iOS").append
这会在对象 B 上调用 属性 append
,您没有将任何对象与对象 B 相关联,因此这 return 是一个空引用。
str.replacingRangeWithString(NSMakeRange(6, 5),@"iOS").append(@" ahhhh")
您试图调用您的 "block",但您有一个空引用 => 内存错误。
更新
在这一点上,我最初建议你需要重新考虑你的设计 - 你确实这样做了 - 并且解决方案可能不像你想要的那么简单 - 从那时起我就意识到可能有一个简单的方法...
提供 你只是想用 属性 访问替换方法调用,这样你就可以整齐地将调用链接在一起;也就是说,您无意使用执行不同操作的块调用 configure...
方法;那么您可以在 属性 中动态创建和 return 一个块。这是 append
的大纲。首先将 属性 设为只读:
@property(nonatomic, readonly) MethodAppend append;
然后使用以下方式定义它:
-(MethodAppend)append
{
NSString *copied = self.copy;
return ^(NSString *string){ return [copied stringByAppendingString:string]; };
}
这首先复制字符串,以防调用它的实例是 NSMutableString
,你不知道在调用这个 属性 之后多久会调用该块,并且到那时字符串值可能已经更改。然后它 return 是一个块,它接受所需的参数并调用预期的方法。
这就是所有需要的,没有设置器或配置方法,也没有关联对象。
HTH