3

私はそのようなコードを持っています:

NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(updateFrame)]];
[invocation setTarget:self];
[invocation setSelector:@selector(updateFrame)];
displayLink_ = [[CADisplayLink displayLinkWithTarget:invocation selector:@selector(invoke)] retain];
[displayLink_ setFrameInterval:1];
[displayLink_ addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

iOS 6.0 (5.1 ではこのコードは正常に動作します) では、このコード呼び出しには 2 つのバリアントがあります: EXC_BAD_ACCESS または「認識されていないセレクター "invoke" への呼び出し」。displayLinkWithTarget:selector: メソッドがターゲットを保持していないようです。[呼び出し保持]行を追加すると、コードが正常に動作するようになります。iOS 6.0のバグですか?

4

2 に答える 2

4

これは有用な関連情報であり、回答ではありません。

NSInvokationこの質問に対する実際の回答で行ったように、使用するのではなく、弱いプロキシを使用できます。これは非常に簡単です。コードは次のとおりです。

JAWeakProxy.h:

#import <Foundation/Foundation.h>

@interface JAWeakProxy : NSObject

@property (weak, nonatomic) id  target;

+ (JAWeakProxy*)weakProxyWithTarget:(id)target;

@end

JAWeakProxy.m:

#import "JAWeakProxy.h"

@implementation JAWeakProxy

+ (JAWeakProxy*)weakProxyWithTarget:(id)target
{
    JAWeakProxy* newObj = [self new];
    newObj.target = target;
    return newObj;
}

- (BOOL)respondsToSelector:(SEL)sel
{
    return [_target respondsToSelector:sel] || [super respondsToSelector:sel];
}

- (id)forwardingTargetForSelector:(SEL)sel
{
    return _target;
}

@end

注: これは ARC コードです。ARCを使用autoreleaseweakProxyWithTarget:ない場合は入力する必要があります。

于 2012-12-17T20:00:10.163 に答える
2

私も同じ問題を抱えていました。私は実際には弱い参照が必要ですが、それは強いとして文書化されており、iOS の他のバージョンではそのように動作するため、弱いプロキシ オブジェクトを使用して、セレクターを本当に移動したい場所に転送します。プロキシ オブジェクトが確実に保持されるようにするために、破損していないバージョンの iOS で過剰に保持することなく、破損したバージョンの iOS でプロキシ オブジェクトを安全に保持する方法を見つけなければなりませんでした。私は非常にエレガントな 1 行のソリューションを思いつきました (それを説明する 4 行のコメントの後の行):

JAWeakProxy*    weakSelf = [JAWeakProxy weakProxyWithTarget:self];
_displayLink = [CADisplayLink displayLinkWithTarget:weakSelf selector:@selector(displayLinkUpdate:)];
// Due to a bug in iOS 6, CADisplayLink doesn't retain its target (which it should and is
// documented to do) so we need to ensure a strong reference to the weak proxy object is
// created somewhere. We do this by adding it as an associated object to the display link
// which means that it gets retained for as long as the display link object is alive.
objc_setAssociatedObject(_displayLink, @"Retain the target, bitch!", weakSelf, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

を忘れないでください#import <objc/runtime.h>。関連付けられたオブジェクトを使用すると、表示リンクが編集されたときに解放されdealloc、OS の壊れていないバージョンでは単にオブジェクトが表示リンクによって 2 回保持されることになるため、優れています。

于 2012-12-17T19:49:03.420 に答える