Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 在类别界面/实现中设置新属性_Objective C_Ios_Categories - Fatal编程技术网

Objective c 在类别界面/实现中设置新属性

Objective c 在类别界面/实现中设置新属性,objective-c,ios,categories,Objective C,Ios,Categories,好的,我有这个,但它不起作用: @interface UILabel (touches) @property (nonatomic) BOOL isMethodStep; @end @implementation UILabel (touches) -(BOOL)isMethodStep { return self.isMethodStep; } -(void)setIsMethodStep:(BOOL)boolean { self.isMethodStep = bo

好的,我有这个,但它不起作用:

@interface UILabel (touches)

@property (nonatomic) BOOL isMethodStep;

@end


@implementation UILabel (touches)

-(BOOL)isMethodStep {
    return self.isMethodStep;
}

-(void)setIsMethodStep:(BOOL)boolean {
    self.isMethodStep = boolean;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if(self.isMethodStep){
        // set all labels to normal font:
        UIFont *toSet = (self.font == [UIFont fontWithName:@"Helvetica" size:16]) ? [UIFont fontWithName:@"Helvetica-Bold" size:16] : [UIFont fontWithName:@"Helvetica" size:16];

        id superView = self.superview;
        for(id theView in [(UIView *)superView subviews])
            if([theView isKindOfClass:[UILabel class]])
                [(UILabel *)theView setFont:[UIFont fontWithName:@"Helvetica" size:16]];

        self.font = toSet;
    }
}

@end
如果我去掉了getter和setter方法,那么它就不起作用了。它告诉我需要创建一些getter和setter方法(或者使用@synthel,但是将@synthel放在@implementation中也会出错)。但是使用getter和setter方法,我得到了一个EXC\u坏访问和崩溃。有什么想法吗?谢谢


Tom

不可能通过仅限类别的方法向现有类添加成员和属性

一种可能的解决方法是编写“setter/getter-like”方法,该方法使用一个单例来保存变量,该变量本来就是成员

-(void)setMember:(MyObject *)someObject
{
    NSMutableDictionary *dict = [MySingleton sharedRegistry];
    [dict setObject:someObject forKey:self];
}

-(MyObject *)member
{
    NSMutableDictionary *dict = [MySingleton sharedRegistry];
    return [dict objectforKey:self];
}

当然,也可以编写一个从UILabel继承的自定义类



请注意,现在可以在运行时注入关联对象

编辑:警告:此属性对于类的所有实例都具有唯一值

这对我有效,但只是因为我的应用程序中只有一个此类的实例

#import <AVFoundation/AVFoundation.h>

@interface AVAudioPlayer (AstroAVAudioPlayer)

@property (nonatomic) BOOL redPilot;

@end


#import "AVAudioPlayer+AstroAVAudioPlayer.h"

@implementation AVAudioPlayer (AstroAVAudioPlayer)

BOOL _redPilot;

-(void) setRedPilot:(BOOL)redPilot
{
    _redPilot = redPilot;
}

-(BOOL) redPilot
{
    return _redPilot;
}

@end
#导入
@接口AVAudioPlayer(AstroAVAudioPlayer)
@属性(非原子)BOOL-redPilot;
@结束
#导入“AVAudioPlayer+AstroAVAudioPlayer.h”
@实现AVAudioPlayer(AstroAVAudioPlayer)
布尔(BOOL_)红领航员,;
-(void)setRedPilot:(BOOL)redPilot
{
_redPilot=redPilot;
}
-(BOOL)红领航员
{
返回红领航员;
}
@结束

我找到了一个解决方案,就是给每个要标记的对象一个唯一的标记

我创建了一个UILabel类别,将自定义字体添加到我的所有标签中,但在一些标签上,我希望它们是粗体的,所以我这样做了->

- (void) layoutSubviews {
    [super layoutSubviews];
    [self addCustomFont];   
}

- (void) addCustomFont {
    if (self.tag == 22) {
        [self setFont:[UIFont fontWithName:SEGOE_BOLD size:self.font.pointSize]];
    }else{
        [self setFont:[UIFont fontWithName:SEGOE_LIGHT size:self.font.pointSize]];
    }
}

实际上,有一种方法可能并不理想,但确实有效。
要使其工作,您需要为类X创建一个类别,并且只能在同一个X的子类上使用(例如,类别
UIView(后台)
可以与类
MyView:UIView
一起使用,但不能直接与
UIView
一起使用)

然后


使用此方法,您将需要“重新声明”您的属性,但在此之后,您可以在类别内执行其所有操作。

似乎由于Xcode 7(7.0.1,7A1001),类别中支持属性。我注意到,Xcode现在为核心数据子类生成类别

例如,我得到了以下文件:

Location+CoreDataProperties.h

#import "Location.h"

NS_ASSUME_NONNULL_BEGIN

@interface Location (CoreDataProperties)

@property (nullable, nonatomic, retain) NSNumber *altitude;
@property (nullable, nonatomic, retain) NSNumber *latitude;
@property (nullable, nonatomic, retain) NSNumber *longitude;

@end

NS_ASSUME_NONNULL_END
@interface Location : NSManagedObject

@end

#import "Location+CoreDataProperties.h"
Location+CoreDataProperties.m

#import "Location+CoreDataProperties.h"

@implementation Location (CoreDataProperties)

@dynamic altitude;
@dynamic latitude;
@dynamic longitude;

@end
因此,看起来类别中的属性现在可以工作了。我还没有测试过非核心数据类

我注意到,它们确实将类别文件重新包含到原始类中:

位置.h

#import "Location.h"

NS_ASSUME_NONNULL_BEGIN

@interface Location (CoreDataProperties)

@property (nullable, nonatomic, retain) NSNumber *altitude;
@property (nullable, nonatomic, retain) NSNumber *latitude;
@property (nullable, nonatomic, retain) NSNumber *longitude;

@end

NS_ASSUME_NONNULL_END
@interface Location : NSManagedObject

@end

#import "Location+CoreDataProperties.h"

这允许原始类编辑类别指定的属性。

检查了所有答案,但未找到最常见的解决方案:

#导入
静态无效常数*键;
@接口类名(CategoryName)
@属性(非原子)BOOL-myProperty;
@结束
@实现类名称(CategoryName)
-(BOOL)我的财产{
返回[objc_getAssociatedObject(self,key)布尔值];
}
-(void)setMyProperty:(BOOL)值{
objc_setAssociatedObject(self、key、@(value)、objc_ASSOCIATION_RETAIN);
}
@结束
斯威夫特:

私有结构关联密钥{
静态var keyName=“keyName”
}
分机{
酒吧:任何{
得到{
返回objc_getAssociatedObject(self,&AssociatedKeys.keyName)
}
设置{
objc_setAssociatedObject(self,&AssociatedKeys.keyName,newValue,.objc_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}

您可以在运行时注入关联对象

#import <objc/runtime.h>

@interface UIView (Private)

@property (nonatomic, assign) CGPoint initialTouchPoint;
@property (nonatomic, strong) UIWindow *alertWindow;

@end

@implementation UIView (Private)

@dynamic initialTouchPoint, alertWindow;

- (CGPoint)initialTouchPoint {
    return CGPointFromString(objc_getAssociatedObject(self, @selector(initialTouchPoint)));
}

- (void)setInitialTouchPoint:(CGPoint)initialTouchPoint {
    objc_setAssociatedObject(self, @selector(initialTouchPoint), NSStringFromCGPoint(initialTouchPoint), OBJC_ASSOCIATION_RETAIN);
}

- (void)setAlertWindow:(UIWindow *)alertWindow {
    objc_setAssociatedObject(self, @selector(alertWindow), alertWindow, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UIWindow *)alertWindow {
    return objc_getAssociatedObject(self, @selector(alertWindow));
}

@end
#导入
@接口UIView(专用)
@属性(非原子,赋值)CGPoint initialTouchPoint;
@属性(非原子,强)UIWindow*alertWindow;
@结束
@实现视图(专用)
@动态初始接触点、警报窗口;
-(CGPoint)初始接触点{
返回CGPointFromString(objc_getAssociatedObject(self,@selector(initialTouchPoint));
}
-(无效)setInitialTouchPoint:(CGPoint)initialTouchPoint{
objc_setAssociatedObject(self、@selector(initialTouchPoint)、NSStringFromCGPoint(initialTouchPoint)、objc_ASSOCIATION_RETAIN);
}
-(无效)setAlertWindow:(UIWindow*)alertWindow{
objc_setAssociatedObject(self、@selector(alertWindow)、alertWindow、objc_ASSOCIATION_RETAIN_NONATOMIC);
}
-(UIWindow*)警报窗口{
返回objc_getAssociatedObject(self,@selector(alertWindow));
}
@结束

“或者——当然——编写一个从UILabel继承的自定义类”就不那么麻烦了坏消息,嗯?啊。。。好的,谢谢您应该使用[NSValue-valueWithPointer:self]作为键,而不是self。@Dustin:正如我在编辑中指出的,现在再也没有必要使用这个古老的代码了——如果伪造属性是明智的话。谢谢你的否决票。避免关联对象。“状态不好。”扎布朗,我同意。事实上我从来没用过。但问题是关于类别中的属性。这个叫戴夫·德隆的家伙发布了一个答案,你应该去看看。。。这可能是做你想做的事情的“正确”方式……:)关联引用是解决方案。。。在这里还可以找到很好的教程,您的
isMethodStep
getter是一个无限递归函数。这就是为什么你会遇到EXC坏访问崩溃的原因<代码>自我。isMethodStep等同于
[自我isMethodStep]
。此答案应标记为不正确。上面的实现只为AVAudioPlayer的所有实例分配一个名为_redPilot的属性。换句话说,如果你有三个AVAudioPlayer实例,那么avAudioPlayer1.redPilot==avAudioPlayer2.redPilot==avAudioPlayer3.redPilot总是这样。@nobuller,你是对的,先生。事实上,在我的例子中,我只有一个AVAudioPlayer实例,所以我并不太在意。我在这里回答了这个问题,因为我认为这可能会对某些人有所帮助,比如像我这样的人。我会对答案进行编辑,以便