object-c万能解决bug思路

有关运算符重载

C++ 支持运算符重载,但 Objective-C 中不支持。
然而,Objc 中可以看到下面的用法

id obj = dict[@"keyStr"];  

它和

id obj = [dict objectForKey:@"keyStr"];  

等价。这里的 [] 的用法貌似是一种运算符重载,然而它的名字叫 subscripting。
下面是一个 subscripting 的小例子。通过重载 objectAtIndexedSubscript和objectForKeyedSubscript方法,可以实现 ”整数形式的“ 和 ”object形式的“ 两种 subscripting:

// ========= Person.h ==========  

#import   

@interface Person: NSObject  

-(id) objectAtIndexedSubscript:(NSUInteger)idx;  
-(id) objectForKeyedSubscript:(id)key;  

@property NSString* name1;  
@property NSString* name2;  
@property NSString* name3;  

// ========= Person.m ==========  

#import "Person.h"  

-(id) init {  
    if (self = [super init]) {  
        _name1 = [[NSString alloc] init];  
        _name1 = @"NAME#1";  

        _name2 = [[NSString alloc] init];  
        _name2 = @"NAME#2";  

        _name3 = [[NSString alloc] init];  
        _name3 = @"NAME#3";  
    }  
    return self;  
}  

-(id) objectAtIndexedSubscript:(NSUInteger)idx {  
    switch (idx) {  
        case 0:  
            return _name1;  
        case 1:  
            return _name2;  
        case 2:  
            return _name3;  
        default:  
            return nil;  
    }  
}  

-(id) objectForKeyedSubscript:(id)key {  
    if ([key isEqualToString:@"#0"]) {  
        return _name1;  
    } else if ([key isEqualToString:@"#1"]) {  
        return _name2;  
    } else if ([key isEqualToString:@"#2"]) {  
        return _name3;  
    }  
    return nil;  
}  

// ========= main.m ==========  

#import   

#import "Person.h"  

int main(int argc, const charchar * argv[]) {  
    @autoreleasepool {  
        Person* p = [[Person alloc] init];  

        NSLog(@"p[0]:%@", p[0]);  
        NSLog(@"p[1]:%@", p[1]);  
        NSLog(@"p[2]:%@", p[2]);  
        NSLog(@"p[3]:%@", p[3]);  

        NSLog(@"p[\"#0\"]:%@", p[@"#0"]);  
        NSLog(@"p[\"#1\"]:%@", p[@"#1"]);  
        NSLog(@"p[\"#2\"]:%@", p[@"#2"]);  
        NSLog(@"p[\"#3\"]:%@", p[@"#3"]);  
    }  
    return 0;  
}  

运行结果:

p[0]:NAME#1  
p[1]:NAME#2  
p[2]:NAME#3  
p[3]:(null)  
p["#0"]:NAME#1  
p["#1"]:NAME#2  
p["#2"]:NAME#3  
p["#3"]:(null)  

NSNULL通过运算符重载的方式解决bug和闪退

在IOS过程当中通常会有Obj[key]的取值方式,这种取值方式在数据字典NSDictionary中用的特别多,但当obj=NSNull时程序会直接报下面的错误:

-[NSNull objectForKeyedSubscript:]: unrecognized selector sent to instance 0x1d263a20

NSNull的父类为NSObject,但NSNull和NSObject没有实现objectForKeyedSubscript这个方法,所以调用NSNull[key]的时候会直接报unrecognized selector错误;因此只需在NSNull的拓展函数(拓展函数是IOS中的好东西~good)中实现objectForKeyedSubscript和objectAtIndexedSubscript两个方法并做特殊处理即可解决bug,下面为实现的代码:

//
//  NSNull+Extension.h
//  Volunteer
//
//  Created by long on 15/11/5.
//
//

#import 
#import 

@interface NSNull (Extension)

-(id) objectAtIndexedSubscript:(NSUInteger)idx;
-(id) objectForKeyedSubscript:(id)key;

@end

//
//  NSNull+Extension.m
//  Volunteer
//
//  Created by long on 15/11/5.
//
//

#import "NSNull+Extension.h"

@implementation NSNull (Extension)



-(id) objectAtIndexedSubscript:(NSUInteger)idx {
    return nil;
}

-(id) objectForKeyedSubscript:(id)key {
    return nil;
}
@end

代码引用事例1

int main(int argc, const charchar * argv[]) {  
    @autoreleasepool {  
        NSDictionary *dic;
        NSLog(@"%@",dic["test"]);
    }  
    return 0;  
}  

代码引用事例2

-(void)ReqSuccessDatas:(NSDictionary *)jsonData tag:(NSInteger)tag
{
    _newsContent = jsonData[@"Rows"][@"art_content"];
    [self.tableView reloadData];
}

写好NSNull的拓展实现之后,直接add到项目,无需引入NSNull+Extension.h即可全局使用了。

总结

在项目开发过程当中会出现各种各样的bug和程序闪退,解决思路上可以类似NSNull那样通过重写扩展函数的方式,对特殊函数做处理。

完。

你可能感兴趣的:(菜鸟的私房菜,ios,objective-c,ios)