OC里面如何做到对新对象进行操作,可以对旧对象产生作用?

如题,如果是以@property的形式声明新对象该如何写,如果是在函数里面又该怎样写?(此时无法用@property的属性)

阅读 3.4k
2 个回答

不是很确定是否符合题目要求,感觉题主的要求是想更新一个对象就能对另一个对象造成完全一样的影响,如果是这种,那是一个典型的 proxy 模式,可以用 NSProxy 来实现。

下面这个 gist 实现了一个简单的 ProxyContainer,可以通过操作这个容器来修改里面所有对象。
https://gist.github.com/huandu/0519f6a04bae9378dc7a

因为众所周知的原因,我把 gist 的内容直接贴在这里,方便大家查看。

// Copyright 2015 Huan Du. All rights reserved.
// Licensed under the MIT license that can be found in the LICENSE file.

#import <Foundation/Foundation.h>

@interface ProxyContainer : NSProxy

- (instancetype)initWithObjects:(NSArray *)objects;

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector;
- (void)forwardInvocation:(NSInvocation *)invocation;
@end
// Copyright 2015 Huan Du. All rights reserved.
// Licensed under the MIT license that can be found in the LICENSE file.

#import "ProxyContainer.h"

@interface ProxyContainer ()
@property (nonatomic, strong, readonly) NSArray *managedObjects;
@end

@implementation ProxyContainer

- (instancetype)initWithObjects:(NSArray *)objects
{
    _managedObjects = objects;

    // NSProxy doesn't response init message.
    return self;
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
    id obj = self.managedObjects.firstObject;
    return [obj methodSignatureForSelector:selector];
}

- (void)forwardInvocation:(NSInvocation *)invocation
{
    for (id obj in self.managedObjects) {
        [invocation invokeWithTarget:obj];
    }
}

@end

使用的方法如下所示:

// Copyright 2015 Huan Du. All rights reserved.
// Licensed under the MIT license that can be found in the LICENSE file.

#import <Foundation/Foundation.h>
#import "ProxyContainer.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSMutableArray *arr1 = [[NSMutableArray alloc] init];
        NSMutableArray *arr2 = [[NSMutableArray alloc] init];
        NSMutableArray *arr3 = [[NSMutableArray alloc] init];

        [arr1 addObject:@"Hello"];
        [arr1 addObject:@"world!"];

        [arr2 addObject:@"Oh"];

        id container = [[ProxyContainer alloc] initWithObjects:@[arr1, arr2, arr3]];

        [container addObject:@"Roger"];
        [container addObject:@"that"];

        // arr1 has 4 objects: @"Hello", @"world!", @"Roger", @"that".
        NSLog(@"%@", arr1);

        // arr2 has 3 objects: @"Oh", @"Roger", @"that".
        NSLog(@"%@", arr2);

        // arr3 has 2 objects: @"Roger", @"that".
        NSLog(@"%@", arr3);
    }

    return 0;
}

为什么要这样做呢。为什么不直接操作一个对象,操作一个新对象旧对象也跟着变化这样把简单的事情复杂化,难道你们有什么特殊的需求

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题