首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言入門

Objective-C 動態映射:自動修復 NSString 類型 nil 屬性

     編輯:C 語言入門

應用場景

iOS 專案常將 JSON 反序列化為模型物件。若伺服器回傳欄位缺失或為 null,對應的 NSString* 屬性會保持 nil,後續直接使用易導致崩潰或邏輯異常。需一個通用方法:掃描任意物件的所有屬性,針對型別為 NSString 且值為 nil 者,自動賦值為 @""。

核心實作

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

@interface GMCommonHelper : NSObject
- (void)fixNilData:(id)object;
@end

@implementation GMCommonHelper

- (void)fixNilData:(id)object {
    unsigned int count = 0;
    objc_property_t *props = class_copyPropertyList([object class], &count);
    
    for (unsigned int i = 0; i < count; ++i) {
        objc_property_t prop = props[i];
        const char *name = property_getName(prop);
        const char *attrs = property_getAttributes(prop);
        
        NSString *propName = [NSString stringWithUTF8String:name];
        NSString *propAttrs = [NSString stringWithUTF8String:attrs];
        
        // 屬性型別編碼以 "T@" 開頭,NSString 具體為 T@"NSString"
        if (![object valueForKey:propName] && [propAttrs hasPrefix:@"T@\"NSString\""]) {
            [object setValue:@"" forKey:propName];
        }
    }
    free(props);
}
@end

關鍵點解析

  1. class_copyPropertyList 取得屬性清單,務必在最後 free(props) 釋放記憶體。
  2. property_getAttributes 回傳型別編碼字串,T@"NSString" 代表 NSString 物件型別。
  3. 使用 KVC valueForKey:/setValue:forKey: 動態存取屬性值。
  4. 判斷 !value 涵蓋 nil、NULL、0,對 NSString* 等同於 nil 檢查。

延伸:釋放所有非 readonly 物件屬性

- (void)releaseProperties {
    unsigned int count = 0;
    objc_property_t *props = class_copyPropertyList([self class], &count);
    for (unsigned int i = 0; i < count; ++i) {
        objc_property_t prop = props[i];
        NSString *name = [NSString stringWithUTF8String:property_getName(prop)];
        NSString *attrs = [NSString stringWithUTF8String:property_getAttributes(prop)];
        // T@ 開頭表示物件型別,且無 ",R," 標記代表非 readonly
        if ([attrs hasPrefix:@"T@"] && [attrs rangeOfString:@",R,"].location == NSNotFound) {
            [self setValue:nil forKey:name];
        }
    }
    free(props);
}

型別編碼速查

編碼含義
cchar
iint
sshort
llong
qlong long
ffloat
ddouble
@Objective-C 物件 (id)
#Class
:SEL
[陣列型別]陣列
{結構體名=成員...}結構體

更多編碼細節請參考 Apple 官方文件 Objective-C Runtime Programming Guide > Type Encodings。

總結

透過 Objective-C Runtime 的反射能力,僅需十幾行程式碼即可實現「任意模型、任意屬性、自動修復 nil 字串」的通用工具,極大減少手動防禦性程式碼,提升專案健壯性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved