2010-11-04 67 views
13

好了,所以我有這個,但它不會工作:設置類別界面新特性/實現

@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方法(或使用@synthesize - 但將@synthesize放在@implementation中也會引發錯誤)。但是通過getter和setter方法,我得到了一個EXC_BAD_ACCESS和一個崩潰。有任何想法嗎?由於

湯姆

+0

這傢伙'Dave DeLong'發佈了一個答案,你應該檢查出...這可能是「正確」的方式來做你想做的...... :) [這裏是鏈接...](http ://stackoverflow.com/questions/4146183/instance-variables-for-objective-c-categories) – 2011-07-04 15:54:10

+1

關聯引用解決方案...在這裏http://www.techpaa.com/2012/04/adding找到好的教程-properties-to-categories -.html – ShivaPrasad 2012-04-17 11:47:35

+1

另外,你的'isMethodStep' getter是一個無限遞歸函數。這就是爲什麼你會遇到EXC_BAD_ACCESS崩潰。 'self.isMethodStep'等同於'[self isMethodStep]'。 – 2014-10-06 18:43:33

回答

39

這是不可能通過類成員和屬性添加到現有的類 - 唯一方法。

https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/Category.html

一個可能的解決方法是編寫「二傳手/吸氣式」方法,即使用一個單獨保存變量,這將一直是會員。

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

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

或 - 當然 - 編寫自定義類,從的UILabel


注意,時下一個關聯對象可以在運行時被注入繼承。 The Objective C Programming Language: Associative References

+0

「或 - 當然 - 編寫一個自定義的類,從UILabel繼承」將會不那麼麻煩。 :)壞消息呃?啊...好的,謝謝。 :) – 2010-11-04 19:10:48

+0

+1偉大的答案 – 2011-04-09 02:20:53

+0

在這裏你去:-) – 2011-04-11 02:59:58

0

編輯:警告:此屬性將具有該類的所有實例的唯一值。

這對我有效,但只是因爲我的應用程序中只有這個類的一個實例。

#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 
+2

此答案應被標記爲不正確。上面的實現僅爲AVAudioPlayer的所有實例分配了一個名爲_redPilot的屬性。換句話說,如果你有三個AVAudioPlayer實例,那麼avAudioPlayer1.redPilot == avAudioPlayer2.redPilot == avAudioPlayer3.redPilot總是。 – noobular 2013-06-27 21:26:21

+1

@nobular,先生,您是對的。事實上,在我的情況下,我只有一個AVAudioPlayer實例,所以我對此並不在意。無論如何,我在這裏回答了這個問題,因爲我認爲這可能對某人有幫助,例如像我這樣的人。我會編輯答案,以便警告上述問題。 – 2013-06-28 08:38:48

+0

下面是我已經在過去用於解決有關類別的缺乏特性的技術:http://www.techpaa.com/2012/04/adding-properties-to-categories-and.html – noobular 2013-08-04 07:00:43

0

我發現這個解決方案只是給每個你想要標記的對象一個唯一標籤。

我做了一個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]]; 
    } 
} 
1

其實有一個辦法,這可能不理想,但確實有效。
對於它的工作,你需要創建一個類X的類別,只能在子類相同的X的使用(例如UIView (Background)類可以用​​3210類使用,但不能直接與UIView

// UIView+Background.h 

@interface UIView (Background) 

@property (strong, nonatomic) NSString *hexColor; 

- (void)someMethodThatUsesHexColor; 

@end 

// UIView+Background.h 

@implementation UIView (Background) 

@dynamic hexColor; // Must be declared as dynamic 

- (void)someMethodThatUsesHexColor { 
    NSLog(@"Color %@", self.hexColor); 
} 

@end 

然後

// MyView.m 

#import "UIView+Background.h" 

@interface MyView : UIView 

@property (strong, nonatomic) NSString *hexColor; 

@end 

@implementation MyView() 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    [self setHexColor:@"#BABACA"]; 
    [self someMethodThatUsesHexColor]; 
} 

@end 

使用這種方法,你需要「重新聲明」的性質,但在那之後,你可以做所有的操縱您的類別內。

0

看起來好像自從Xcode 7(7.0.1,7A1001),在類別中支持屬性。我注意到Xcode現在生成類別爲核心數據的子類。

例如,我得到的文件:

位置+ 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 

位置+ CoreDataProperties.m

#import "Location+CoreDataProperties.h" 

@implementation Location (CoreDataProperties) 

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

@end 

所以看起來像類的屬性現在可能工作。我還未在非核心數據類上進行測試。

我已經注意到的是,他們做包括類文件放回原班:

Location.h

@interface Location : NSManagedObject 

@end 

#import "Location+CoreDataProperties.h" 

這使得原班編輯由指定的屬性類別。

3

經過所有的答案,並沒有找到最常見的解決方案:

#import <objc/runtime.h> 

static void const *key; 

@interface ClassName (CategoryName) 
@property (nonatomic) BOOL myProperty; 
@end 

@implementation ClassName (CategoryName) 
- (BOOL)myProperty { 
    return [objc_getAssociatedObject(self, key) boolValue]; 
} 

- (void)setMyProperty:(BOOL)value { 
    objc_setAssociatedObject(self, key, @(value), OBJC_ASSOCIATION_RETAIN); 
} 
@end 
+0

完美的解決方案!謝謝! – 2016-11-30 19:54:23

0

運行時您可以注入相關的對象。

#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