NSProxy对于那些尚不存在的对象来说,它们看起来效果非常好.例如.
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
return [self.target methodSignatureForSelector:sel];
}
- (void)forwardInvocation:(NSInvocation *)invocation {
[invocation invokeWithTarget:self.target];
}
Run Code Online (Sandbox Code Playgroud)
上面的代码将透明地将任何方法调用传递给代理所代表的目标.但是,它似乎没有处理目标上的KVO观察和通知.我试图使用一个NSProxy子类代表要传递给的对象NSTableView,但我收到以下错误.
Cannot update for observer <NSAutounbinderObservance 0x105889dd0> for
the key path "objectValue.status" from <NSTableCellView 0x105886a80>,
most likely because the value for the key "objectValue" has changed
without an appropriate KVO notification being sent. Check the
KVO-compliance of the NSTableCellView class.
Run Code Online (Sandbox Code Playgroud)
有没有办法让透明NSProxy符合KVO标准?
我正在尝试为我的UIViews添加功能(根据状态配置CALayers),设置一个NSProxy子类代替我选择的任何UIView.这是我尝试过的:
在我的NSProxy子类中,我有以下代码:
#pragma mark Initialization / Dealloc
- (id)initWithView:(UIView *)view
{
delegate = view;
[delegate retain];
return self;
}
- (void)dealloc
{
[delegate release];
[super dealloc];
}
#pragma mark Proxy Methods
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
[anInvocation setTarget:delegate];
[anInvocation invoke];
return;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
return [delegate methodSignatureForSelector:aSelector];
}
- (BOOL)respondsToSelector:(SEL)aSelector
{
BOOL rv = NO;
if ([delegate respondsToSelector:aSelector]) { rv = YES; }
return rv;
}
Run Code Online (Sandbox Code Playgroud)
并且,以这种方式使用我的NSProxy子类:
UILabel *label = [[HFMultiStateProxy alloc] initWithView:[[[UILabel alloc] initWithFrame:cellFrame] autorelease]];
label.text = text; …Run Code Online (Sandbox Code Playgroud) 该NSProxy类参考这样说:
通常,将代理的消息转发到真实对象或使代理加载(或转换为自身)真实对象.
"将自身转化为真实对象"究竟会如何运作?
为了使事情更具体一些,假设class Foo有一个方法newFooWithString:,它接受一个字符串并返回一个新的实例Foo.是否有可能设置一个NSProxy坐在周围,如果pleaseBecomeAFooUsingString: @"bar"收到一条消息,将自身转换为[Foo newFooWithString: @"bar"]占用相同的内存,而不会弄乱可能存在的其他对自身的引用?
在ARC,我有一个对象,Child有一个weak属性,parent.我正在尝试编写一些测试Child,并且我正在parent使用它来嘲弄它的属性OCMock.
在ARC下,NSProxy使用合成的弱属性设置器设置子类不会设置属性...设置弱属性后的行,检查它显示它已经存在nil.这是具体的例子:
@interface Child : NSObject
@property (nonatomic, weak) id <ParentInterface>parent;
@end
@implementation Child
@synthesize parent = parent_;
@end
// ... later, inside a test class ...
- (void)testParentExists
{
// `mockForProtocol` returns an `NSProxy` subclass
//
OCMockObject *aParent = [OCMockObject mockForProtocol:@protocol(ParentInterface)];
assertThat(aParent, notNilValue());
// `Child` is the class under test
//
Child *child = [[Child alloc] init];
assertThat(child, notNilValue());
assertThat(child.parent, nilValue()); …Run Code Online (Sandbox Code Playgroud) unit-testing objective-c ocmock nsproxy automatic-ref-counting
我一直在想为什么NSProxy类如此重要.为什么对象需要将其实例变量保存在其他对象中?我需要一些例子来了解何时使用它.谢谢!
NSProxy类有哪些用途.为什么您希望能够获得不存在的对象的描述?
如何NSProxy在 Swift 中创建子类?
尝试添加任何init方法都会失败并出现错误:“无法在初始化程序之外调用超级初始化”或“从初始化程序返回之前,不会在所有路径上调用超级初始化”
使用 Objective-C 子类作为基类是可行的,但感觉更像是一种 hack:
// Create a base class to use instead of `NSProxy`
@interface WorkingProxyBaseClass : NSProxy
- (instancetype)init;
@end
@implementation WorkingProxyBaseClass
- (instancetype)init
{
if (self) {
}
return self;
}
@end
// Use the newly created Base class to inherit from in Swift
import Foundation
class TestProxy: WorkingProxyBaseClass {
override init() {
super.init()
}
}
Run Code Online (Sandbox Code Playgroud) 在OCMockito中,使用NSProxy实现测试双精度.实例中的双重实现-respondsToSelector:如下:
- (BOOL)respondsToSelector:(SEL)aSelector {
return [_mockedClass instancesRespondToSelector:aSelector];
}
Run Code Online (Sandbox Code Playgroud)
但是对于一个类的实现-respondsToSelector:这样的双重实现:
- (BOOL)respondsToSelector:(SEL)aSelector {
return [_mockedClass respondsToSelector:aSelector];
}
Run Code Online (Sandbox Code Playgroud)
这一切都适用于32位运行时.例如,如果_mockedClass是[NSString class],则代理正确回答它响应选择器+pathWithComponents:
但在64位运行时,它崩溃了:
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: EXC_I386_GPFLT
Application Specific Information:
objc[1868]: GC: forcing GC OFF because OBJC_DISABLE_GC is set
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libobjc.A.dylib 0x00007fff95cbffc6 cache_getImp + 6
1 libobjc.A.dylib 0x00007fff95ccd1dc lookUpImpOrForward + 50
2 libobjc.A.dylib 0x00007fff95ccd198 lookUpImpOrNil + …Run Code Online (Sandbox Code Playgroud) 我目前正在研究一个NSProxy拦截某些消息的子类,并且从不将它们转发给任何人,只是处理它们,所以这些方法从未真正存在过.而这里出现了问题,显然编译器开始抱怨缺少方法实现,我无法弄清楚如何阻止它,向接口添加存根方法只是为了让编译器关闭不起作用因为方法是任意形成的,我不知道它们(为了使它更具体,我要求这个项目).
理想情况下,我想告诉编译器它根本不应该对这个特定的类进行任何方法检查,但是因为这似乎不太可能,我也很乐意以某种方式#pragma或任何其他方式(不包括关闭编译整个项目/文件中的每个警告!)
我需要使用Swift在iOS中创建代理模式
我已经使用Objective C尝试过了,这里是代码
MyProtocol.h
#import <Foundation/Foundation.h>
@protocol MyProtocol <NSObject>
@required
-(void)testMessage;
@end
Run Code Online (Sandbox Code Playgroud)
测试宝
#import <Foundation/Foundation.h>
#import "MyProtocol.h"
@interface TestBO : NSObject <MyProtocol>
@end
Run Code Online (Sandbox Code Playgroud)
测试版
#import "TestBO.h"
@implementation TestBO
-(void)testMessage{
NSLog(@"Test Message");
}
@end
Run Code Online (Sandbox Code Playgroud)
TestProxyHandler.h
#import <Foundation/Foundation.h>
@interface TestProxyHandler : NSProxy
@property (nonatomic, strong) id object;
- (instancetype)initWithProtocol:(Protocol *)protocol andObject:(Class)clazz;
- (void)forwardInvocation:(NSInvocation *)invocation;
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector;
@end
Run Code Online (Sandbox Code Playgroud)
TestProxyHandler.m
#import "TestProxyHandler.h"
#import "TestBO.h"
@implementation TestProxyHandler
- (instancetype)initWithProtocol:(Protocol *)protocol andObject:(Class)clazz{
if ([clazz conformsToProtocol:@protocol(MyProtocol)]) {
self.object = [[clazz alloc] init];
}else{
NSLog(@"Error it does …Run Code Online (Sandbox Code Playgroud) 是否NSProxy真正落实-autorelease和-release?如果没有,我是否需要手动dealloc NSProxy实例?(请假设我没有使用GC).
谢谢你为我解决这个问题.
nsproxy ×11
objective-c ×8
cocoa ×3
ios ×2
swift ×2
calayer ×1
clang ×1
class-method ×1
cocoa-touch ×1
iphone ×1
llvm ×1
ocmock ×1
proxy ×1
swift2 ×1
uilabel ×1
uiview ×1
unit-testing ×1