You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Objective-C如何将单例Participant改造为支持多实例并更新属性?

核心改造点

  • 移除原有单例实现,支持直接创建多实例
  • 新增指定初始化方法,创建实例时必须传入唯一标识
  • 修正属性命名错误:id为OC内置关键字,重命名为pid避免编译错误
  • 修正属性内存修饰符:NSString类型从assign改为copy,避免野指针问题
  • 类扩展中声明属性为readwrite,实现内部可修改、外部只读的访问控制
  • 调整通知监听逻辑:仅当通知携带的目标id和当前实例id匹配时,才更新自身属性
  • 补全name、gender、pid三个属性的更新分支逻辑

完整代码实现

Participant.h 文件

#import <Foundation/Foundation.h>

@interface Participant : NSObject
@property(nonatomic, copy, readonly) NSString *name;
@property(nonatomic, copy, readonly) NSString *pid; // 原id属性,因OC关键字限制重命名为pid
@property(nonatomic, copy, readonly) NSString *gender;

/// 指定初始化方法,必须传入唯一标识pid
- (instancetype)initWithPid:(NSString *)pid;
@end

Participant.m 文件

#import "Participant.h"

@interface Participant ()
@property(nonatomic, copy, readwrite) NSString *name;
@property(nonatomic, copy, readwrite) NSString *pid;
@property(nonatomic, copy, readwrite) NSString *gender;
@end

@implementation Participant

- (instancetype)initWithPid:(NSString *)pid {
    if (self = [super init]) {
        _pid = pid;
        [self setAllValueNil];
        [self initNotificationObserver];
    }
    return self;
}

// 禁用默认init方法,强制走指定初始化逻辑
- (instancetype)init {
    NSAssert(NO, @"请使用initWithPid:方法创建Participant实例");
    return nil;
}

- (void)setAllValueNil {
    _name = nil;
    _gender = nil;
}

- (void)initNotificationObserver {
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(receiveNotification:)
                                                 name:@"participantReciever"
                                               object:nil];
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)receiveNotification:(NSNotification *)notification {
    if (![notification.name isEqualToString:@"participantReciever"]) return;
    NSDictionary *userInfo = notification.userInfo;
    
    // 匹配目标pid,不一致直接跳过
    if (![userInfo[@"targetPid"] isEqualToString:self.pid]) return;
    id value = userInfo[@"value"];
    if (!value) return;
    
    NSString *type = userInfo[@"type"];
    if ([type isEqualToString:@"setName"]) {
        self.name = value;
    } else if ([type isEqualToString:@"setGender"]) {
        self.gender = value;
    } else if ([type isEqualToString:@"resetPid"]) {
        self.pid = value;
    }
}

@end

使用示例

// 1. 创建多个实例存入数组
Participant *p1 = [[Participant alloc] initWithPid:@"user_001"];
Participant *p2 = [[Participant alloc] initWithPid:@"user_002"];
NSArray *participantArray = @[p1, p2];

// 2. 发送通知更新指定实例属性:更新user_001的姓名
[[NSNotificationCenter defaultCenter] postNotificationName:@"participantReciever"
                                                    object:nil
                                                  userInfo:@{
                                                      @"targetPid": @"user_001",
                                                      @"type": @"setName",
                                                      @"value": @"张三"
                                                  }];

// 3. 验证结果:p1.name = 张三,p2.name 仍为nil
NSLog(@"p1姓名:%@,p2姓名:%@", p1.name, p2.name);

内容的提问来源于stack exchange,提问作者Alwaysblue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 07:15:03