来自目标C,您可以objc_setAssociatedObject在两个对象之间调用函数以使它们维护一个引用,如果在运行时您不希望销毁对象直到其引用也被删除,这可能很方便.斯威夫特有什么类似的东西吗?
据我所知,由于XCode 4.4 @synthesize将自动生成属性访问器.但是刚才我已经阅读了一些代码示例NSUndoManager,并在代码中注意到它@synthesize是明确添加的.喜欢:
@interface RootViewController ()
@property (nonatomic, strong) NSDateFormatter *dateFormatter;
@property (nonatomic, strong) NSUndoManager *undoManager;
@end
@implementation RootViewController
//Must explicitly synthesize this
@synthesize undoManager;
Run Code Online (Sandbox Code Playgroud)
我现在感到困惑...... @synthesize我什么时候应该明确地添加到我的代码中?
有人可以向我解释Objective C中类别和继承之间的区别吗?我已经阅读了维基百科中的条目,并且对类别的讨论与继承没有任何不同.我还在"打开iPhone开发"一书中查看了有关该主题的讨论,但我仍然没有得到它.
我通过关联引用将对象B附加到对象A.对象B观察对象A到KVO的一些属性.
问题是对象B似乎在对象A 之后被释放,这意味着它太迟了以将其自身移除为对象A的KVO观察者.我知道这是因为我得到了NSKVODeallocateBreak异常,然后EXEC_BAD_ACCESS在对象B的dealloc中崩溃.
有没有人知道为什么对象B在具有OBJC_ASSOCIATION_RETAIN的对象A之后被释放?解除分配后是否释放相关对象?他们是否被自动释放?有谁知道改变这种行为的方法?
我试图通过类别向类添加一些东西,所以我不能覆盖任何现有的方法(包括dealloc),而且我并不特别想要混乱.在对象A被释放之前,我需要一些方法来解除关联并释放对象B.
编辑 - 这是我正在努力工作的代码.如果在完全取消分配UIImageView之前释放了关联的对象,那么这一切都可以正常工作.我所看到的唯一解决方案是在我自己的dealloc方法中调整,并调回原来以调用它.但这真的很混乱.
ZSPropertyWatcher类的要点是KVO需要一个标准的回调方法,我不想替换UIImageView,以防它自己使用它.
的UIImageView + Loading.h
@interface UIImageView (ZSShowLoading)
@property (nonatomic) BOOL showLoadingSpinner;
@end
Run Code Online (Sandbox Code Playgroud)
的UIImageView + Loading.m
@implementation UIImageView (ZSShowLoading)
#define UIIMAGEVIEW_SPINNER_TAG 862353453
static char imageWatcherKey;
static char frameWatcherKey;
- (void)zsShowSpinner:(BOOL)show {
if (show) {
UIActivityIndicatorView *spinnerView = (UIActivityIndicatorView *)[self viewWithTag:UIIMAGEVIEW_SPINNER_TAG];
if (!spinnerView) {
spinnerView = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge] autorelease];
spinnerView.tag = UIIMAGEVIEW_SPINNER_TAG;
[self addSubview:spinnerView];
[spinnerView startAnimating];
}
[spinnerView setEvenCenter:self.boundsCenter];
} else {
[[self viewWithTag:UIIMAGEVIEW_SPINNER_TAG] removeFromSuperview];
}
}
- …Run Code Online (Sandbox Code Playgroud) 我想使用一个类别来创建原始类的方法作为属性.
A类:
@interface ClassA
- (NSString*)foo;
@end
Run Code Online (Sandbox Code Playgroud)
A类
@interface ClassA (Properties)
- (void)someCategoryMethod;
@property (nonatomic, readonly) NSString *foo;
@end
Run Code Online (Sandbox Code Playgroud)
现在,当我这样做时,它似乎工作(编辑:也许它不起作用,它不抱怨,但我看到奇怪),但它给了我警告,因为我没有合成我的类别实现中的属性.我怎么告诉编译器一切都很好,因为原来的类为我合成了属性?
当使用关联对象,从iOS 4和OSX 10.6开始提供Objective-C运行时功能时,必须定义用于在运行时存储和检索对象的密钥.
典型的用法是定义如下的密钥
static char const * const ObjectTagKey = "ObjectTag";
Run Code Online (Sandbox Code Playgroud)
然后使用是存储对象
objc_setAssociatedObject(self, ObjectTagKey, newObjectTag, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
Run Code Online (Sandbox Code Playgroud)
并检索它
objc_getAssociatedObject(self, ObjectTagKey);
Run Code Online (Sandbox Code Playgroud)
(例如http://oleb.net/blog/2011/05/faking-ivars-in-objc-categories-with-associative-references/)
是否有更简洁的方法来定义关联的对象键,这不涉及额外变量的声明?
我正在尝试在我的objective-c类别上使用Associated Objects,我收到了这个警告.
Implicit declaration of function 'objc_getAssociatedObject' is invalid in C99
Run Code Online (Sandbox Code Playgroud)
如果这有所作为,我也会使用arc.
我正在使用一个类别NSAttributedString (Additions),我真的需要一种方法来添加一个属性BOOL(指示字符串是否是HTML标记).我知道类别不应该有属性,但这就是我需要的方式.我累了写自己的吸气剂和制定者,但它没有用.这怎么办?
我只是想问是否可以通过类别添加实例变量.我的特殊问题是,我需要将一个NSIndexPath属性添加到ASIHTTPRequest对象,但我不想将ASIHTTPRequest子类化为原则问题.
我有什么选择吗?
谢谢你的回答,克里斯蒂安
我尝试扩展cocos2d的SimpleAudioEngine的功能,能够一个接一个地播放几种音效作为某种链.我尝试使用扩展程序执行此操作.但是我现在意识到我可能还需要一个iVar来记住所有声音文件的名称,还有一个要记住当前播放的声音.
但似乎我无法在类别中添加iVars.相反,我尝试使用扩展,但似乎它们需要在类的原始.m文件中,这样也无法工作.还有另一种方式,允许我这样做吗?
带有类别的标题
#import <Foundation/Foundation.h>
@interface SimpleAudioEngine(SoundChainHelper)<CDLongAudioSourceDelegate>
-(void)playSoundChainWithFileNames:(NSString*) filename, ...;
@end
Run Code Online (Sandbox Code Playgroud)
和.m文件扩展名为:
#import "SoundChainHelper.h"
@interface SimpleAudioEngine() {
NSMutableArray* soundsInChain;
int currentSound;
}
@end
@implementation SimpleAudioEngine(SoundChainHelper)
// read in all filenames and start off playing process
-(void)playSoundChainWithFileNames:(NSString*) filename, ... {
soundsInChain = [[NSMutableArray alloc] initWithCapacity:5];
va_list params;
va_start(params,filename);
while (filename) {
[soundsInChain addObject:filename];
filename = va_arg(params, NSString*);
}
va_end(params);
currentSound = 0;
[self cdAudioSourceDidFinishPlaying:nil];
}
// play first file, this will also always automatically be called as soon as the previous …Run Code Online (Sandbox Code Playgroud) objective-c ×8
categories ×3
properties ×3
iphone ×2
cocoa ×1
cocoa-touch ×1
identify ×1
inheritance ×1
ios ×1
nsindexpath ×1
object ×1
oop ×1
swift ×1
synthesize ×1