Objective-C学习知识点

Objective-C学习知识点_第1张图片
OC知识点.png

一、面向对象


#import 

@interface People : NSObject
    @property(nonatomic,copy)NSString* name;
    @property(nonatomic,assign)NSInteger age;
@end
#import "People.h"

@implementation People
    @synthesize  name =  _name;
-(NSString *)name
    {
        return _name;
    }
-(void)setName:(NSString *)name
    {
        _name = name;
    }
@end

注意::@property默认给该属性生成getter和setter方法,当getter和setter方法同时被重写时,则系统就不会自动生成getter和setter方法了,也不会自动帮你生成_num变量,所以不会识别。解决办法声明@synthesize name = _name;

二、内存处理(ARC)

alloc:开辟内存空间,让被开辟的内存空间的引用计数变为1.

assign:赋值属性,不改变引用计数

retain:MRC下让内存空间的引用计数加1.

copy: 把某一内存区域的内容拷贝一份,拷贝到新的内存空间里去,被拷贝区域的引用计数不变,新的内存区域的引用计数为1.必须遵循NSCopying协议

release:MRC下让内存空间的引用计数减1.

autorelease:在缓冲池销毁时让内存空间的引用计数减1.

dealloc:当对象引用计数为0的时候,由对象自动调用.并且如果要有实例变量的话就要重写dealloc方法.重写时先子类后父类。

strong:在ARC下使用相当于retain

@protocol NSCopying

- (id)copyWithZone:(nullable NSZone *)zone;

@end

@protocol NSMutableCopying

- (id)mutableCopyWithZone:(nullable NSZone *)zone;

@end

三、Category、Protocol、 Block

Category扩展iOS原生类使其更加强大

#import 

@interface UIColor (Hex)
+(UIColor*)colorWithHexString:(NSString*)color;

+(UIColor*)colorWithHexString:(NSString*)color alpha:(CGFloat)alpha;
@end
#import "UIColor+Hex.h"

@implementation UIColor (Hex)
+(UIColor *)colorWithHexString:(NSString *)color alpha:(CGFloat)alpha
{
    NSString *cString = [[color stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
    
    if(cString.length < 6){
        return [UIColor clearColor];
    }
    
    if([cString hasPrefix:@"0X"]){
        cString = [cString substringFromIndex:2];
    }
    
    if([cString hasPrefix:@"#"]){
        cString = [cString substringFromIndex:1];
    }
    
    if (cString.length !=6) {
        return [UIColor clearColor];
    }
    
    NSRange range;
    range.location = 0;
    range.length = 2;
    
    NSString *rString = [cString substringWithRange:range];
    
    range.location = 2;
    
    NSString *gString = [cString substringWithRange:range];
    
    range.location = 4;
    
    NSString *bString = [cString substringWithRange:range];
    
    unsigned int r,g,b;
    
    [[NSScanner scannerWithString:rString] scanHexInt:&r];
    [[NSScanner scannerWithString:gString]scanHexInt:&g];
    [[NSScanner scannerWithString:bString]scanHexInt:&b];
    
    return [UIColor colorWithRed:((float)r/255.0f) green:((float)g/255.0f) blue:((float)b/255.0) alpha:alpha];

}

+(UIColor *)colorWithHexString:(NSString *)color
{
    return [self colorWithHexString:color alpha:1.0f];
}

Protocol

@protocol NSCoding

- (void)encodeWithCoder:(NSCoder *)aCoder;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder; // NS_DESIGNATED_INITIALIZER

@end

Extension类内属性和方法不会被继承

#import "XFFBusinessViewController.h"

@interface XFFBusinessViewController ()

@end

@implementation XFFBusinessViewController

@end

Block


Objective-C学习知识点_第2张图片
Block.png

Block重命名的写法是
1.将函数方法声明名用()包裹起来,并在命名方法名前加上^
2.去除返回值类型前的()


#if NS_BLOCKS_AVAILABLE
typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);
#endif

Block值的写法
1.将函数实现部分返回值和方法名替换为^就可以了。

四、Copy、KVC/KVO

KVC

一个对象在调用setValue的时候,(1)首先根据方法名找到运行方法的时候所需要的环境参数。(2)他会从自己isa指针结合环境参数,找到具体的方法实现的接口。(3)再直接查找得来的具体的方法实现。

@interface NSObject(NSKeyValueCoding)
#if FOUNDATION_SWIFT_SDK_EPOCH_AT_LEAST(8)
@property (class, readonly) BOOL accessInstanceVariablesDirectly;
#endif

- (nullable id)valueForKey:(NSString *)key;
- (void)setValue:(nullable id)value forKey:(NSString *)key;
- (BOOL)validateValue:(inout id _Nullable * _Nonnull)ioValue forKey:(NSString *)inKey error:(out NSError **)outError;
- (NSMutableArray *)mutableArrayValueForKey:(NSString *)key;
- (NSMutableOrderedSet *)mutableOrderedSetValueForKey:(NSString *)key NS_AVAILABLE(10_7, 5_0);
- (NSMutableSet *)mutableSetValueForKey:(NSString *)key;
- (nullable id)valueForKeyPath:(NSString *)keyPath;
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;
- (BOOL)validateValue:(inout id _Nullable * _Nonnull)ioValue forKeyPath:(NSString *)inKeyPath error:(out NSError **)outError;
- (NSMutableArray *)mutableArrayValueForKeyPath:(NSString *)keyPath;
- (NSMutableOrderedSet *)mutableOrderedSetValueForKeyPath:(NSString *)keyPath NS_AVAILABLE(10_7, 5_0);
- (NSMutableSet *)mutableSetValueForKeyPath:(NSString *)keyPath;
- (nullable id)valueForUndefinedKey:(NSString *)key;
- (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key;
- (void)setNilValueForKey:(NSString *)key;
- (NSDictionary *)dictionaryWithValuesForKeys:(NSArray *)keys;
- (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues;

@end

KVO

1)使用了KVC
使用了KVC,如果有访问器方法,则运行时会在访问器方法中调用will/didChangeValueForKey:方法;
没用访问器方法,运行时会在setValue:forKey方法中调用will/didChangeValueForKey:方法。
2)有访问器方法
运行时会重写访问器方法调用will/didChangeValueForKey:方法。
因此,直接调用访问器方法改变属性值时,KVO也能监听到。
3)显示调用will/didChangeValueForKey:方法。

#import "ViewController.h"
#import "People.h"

@interface ViewController ()
    @property(nonatomic,strong)People *p;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    People *p = [[People alloc]init];
    self.p = p;
    [p setValue:@"张三" forKey:@"name"];
    [p addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:@"ThisIsMyKVOContextNotSuper"];
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
        if (object == _p && [keyPath isEqualToString:@"name"]) {
            
        }else{
            [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
        }
    }

- (void)dealloc{
    [self.p removeObserver:self forKeyPath:@"name"];
}


@end

五、Foundation框架

1.结构体(NSRange)

typedef struct _NSRange {
    NSUInteger location;
    NSUInteger length;
} NSRange;

2.NSString

#import 
/*
 NSString : 不可变字符串
 
 NSMutableString : 可变字符串
 */


int main()
{
    
    NSMutableString *s1 = [NSMutableString stringWithFormat:@"my age is 10"];
    // 拼接内容到s1的后面
    [s1 appendString:@" 11 12"];
    
    // 获取is的范围
    NSRange range = [s1 rangeOfString:@"is"];
    [s1 deleteCharactersInRange:range];
    
    NSString *s2 = [NSString stringWithFormat:@"age is 10"];
    
    NSString *s3 = [s2 stringByAppendingString:@" 11 12"];
    
    
    NSLog(@"s1=%@, s2=%@", s1, s2);
    
    return 0;
}

void stringExport()
{
    // 字符串的导出
    [@"Jack\nJack" writeToFile:@"/Users/apple/Desktop/my.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];
    
    
    NSString *str = @"4234234";
    NSURL *url = [NSURL fileURLWithPath:@"/Users/apple/Desktop/my2.txt"];
    [str writeToURL:url atomically:YES encoding:NSUTF8StringEncoding error:nil];
}

void stringCreate()
{
    /*
     1.字符串的创建
     */
    NSString *s1 = @"jack";
    
    //NSString *s2 = [[NSString alloc] initWithString:@"jack"];
    
    NSString *s3 = [[NSString alloc] initWithFormat:@"age is %d", 10];
    
    // C字符串 --> OC字符串
    NSString *s4 = [[NSString alloc] initWithUTF8String:"jack"];
    // OC字符串 --> C字符串
    const char *cs = [s4 UTF8String];
    
    // NSUTF8StringEncoding 用到中文就可以用这种编码
    NSString *s5 = [[NSString alloc] initWithContentsOfFile:@"/Users/apple/Desktop/1.txt" encoding:NSUTF8StringEncoding error:nil];
    
    
    // URL : 资源路径
    // 协议头://路径
    // file://
    // ftp://
    // http://weibo.com/a.png
    
    
    // http://www.baidu.com
    
    // NSURL *url = [[NSURL alloc] initWithString:@"file:///Users/apple/Desktop/1.txt"];
    NSURL *url = [NSURL fileURLWithPath:@"/Users/apple/Desktop/1.txt"];
    
    NSString *s6 = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"s6=\n%@", s6);
    
    
    /*
     一般都会有一个类方法跟对象方法配对
     [NSURL URLWithString:<#(NSString *)#>];
     [NSString stringWithFormat:@""];
     [NSString stringWithContentsOfFile:<#(NSString *)#> encoding:<#(NSStringEncoding)#> error:<#(NSError *__autoreleasing *)#>];
     
     */

}

3.NSArray

#import 
#import "Person.h"


/*
 
NSArray :不可变数组
 
 
NSMutableArray : 可变数组
 */

int main()
{
    // @[] 只创建不可变数组NSArray
    /* 错误写法
    NSMutableArray *array = @[@"jack", @"rose"];
    
    [array addObject:@"jim"];
    */
    
    
    //NSArray *array = @[@"jack", @"rose"];
    
    return 0;
}

// 可变数组的基本使用
void use3()
{
    NSMutableArray *array = [NSMutableArray arrayWithObjects:@"rose", @"jim", nil];
    
    // 添加元素
    [array addObject:[[Person alloc] init]];
    
    [array addObject:@"jack"];
    
    // 删除元素
    //[array removeAllObjects];
    // 删除指定的对象
    // [array removeObject:@"jack"];
    [array removeObjectAtIndex:0];
    
    // 错误写法
    // [array addObject:nil];
    
    
    NSLog(@"%@", array);
    
    NSLog(@"%ld", array.count);
}

// 遍历数组
void use2()
{
    Person *p = [[Person alloc] init];
    
    NSArray *array = @[p, @"rose", @"jack"];
    
    //    for (int i = 0; i

4.NSFileManager

#import 


// 计算文件的代码行数
/*
 path : 文件的全路径(可能是文件夹、也可能是文件)
 返回值 int :代码行数
 */
NSUInteger codeLineCount(NSString *path)
{
    // 1.获得文件管理者
    NSFileManager *mgr = [NSFileManager defaultManager];
    
    // 2.标记是否为文件夹
    BOOL dir = NO; // 标记是否为文件夹
    // 标记这个路径是否存在
    BOOL exist = [mgr fileExistsAtPath:path isDirectory:&dir];
    
    // 3.如果不存在,直接返回0
    if(!exist)
    {
        NSLog(@"文件路径不存在!!!!!!");
        return 0;
    }
    
    // 代码能来到着,说明路径存在
    
    
    if (dir)
    { // 文件夹
        // 获得当前文件夹path下面的所有内容(文件夹、文件)
        NSArray *array = [mgr contentsOfDirectoryAtPath:path error:nil];
        
        // 定义一个变量保存path中所有文件的总行数
        int count = 0;
        
        // 遍历数组中的所有子文件(夹)名
        for (NSString *filename in array)
        {
            // 获得子文件(夹)的全路径
            NSString *fullPath = [NSString stringWithFormat:@"%@/%@", path, filename];
            
            // 累加每个子路径的总行数
            count += codeLineCount(fullPath);
        }
        
        return count;
    }
    else
    { // 文件
        // 判断文件的拓展名(忽略大小写)
        NSString *extension = [[path pathExtension] lowercaseString];
        if (![extension isEqualToString:@"h"]
            && ![extension isEqualToString:@"m"]
            && ![extension isEqualToString:@"c"])
        {
            // 文件拓展名不是h,而且也不是m,而且也不是c
            return 0;
        }
        
        // 加载文件内容
        NSString *content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
        
        // 将文件内容切割为每一行
        NSArray *array = [content componentsSeparatedByString:@"\n"];
        
        // 删掉文件路径前面的/Users/apple/Desktop/iOS课堂共享/0722课堂共享/
        NSRange range = [path rangeOfString:@"/Users/apple/Desktop/iOS课堂共享/0722课堂共享/"];
        NSString *str = [path stringByReplacingCharactersInRange:range withString:@""];
        
        // 打印文件路径和行数
        NSLog(@"%@ - %ld", str, array.count);
        
        return array.count;
    }
}

int main()
{
    
    NSUInteger count = codeLineCount(@"/Users/apple/Desktop/iOS课堂共享/0722课堂共享");
    
    NSLog(@"%ld", count);
    return 0;
}

void test()
{
    NSString *str = @"jack\nrose\njim\njake";
    
    [str writeToFile:@"/Users/apple/Desktop/abc.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];
    
    
    NSArray *array = [str componentsSeparatedByString:@"\n"];
    
    for (NSString *line in array)
    {
        NSLog(@"%@", line);
    }
    
    
    //int count = codeLineCount(@"/Users/apple/Desktop/iOS课堂共享/0722课堂共享/0811/代码/04-block/04-block/main.m");
    
    //NSLog(@"count=%d", count);
}

5.NSSet

/*
 NSSet和NSArray的对比
 1> 共同点
 * 都是集合,都能存放多个OC对象
 * 只能存放OC对象,不能存放非OC对象类型(基本数据类型:int、char、float等,结构体,枚举)
 * 本身都不可变,都有一个可变的子类
 
 2> 不同点
 * NSArray有顺序,NSSet没有顺序
 */

#import 

int main()
{
    NSMutableSet *s = [NSMutableSet set];
    
    // 添加元素
    [s addObject:@"hack"];
    
    // 删除元素
    // [s removeObject:<#(id)#>];
    return 0;
}

// set的基本使用
void test()
{
    NSSet *s = [NSSet set];
    
    NSSet *s2 = [NSSet setWithObjects:@"jack",@"rose", @"jack2",@"jack3",nil];
    
    // 随机拿出一个元素
    NSString *str =  [s2 anyObject];
    
    NSLog(@"%@", str);
    
    //NSLog(@"%ld", s2.count);
}

6.NSDictionary

/*
 集合
 1.NSArray\NSMutableArray
 * 有序
 * 快速创建(不可变):@[obj1, obj2, obj3]
 * 快速访问元素:数组名[i]
 
 2.NSSet\NSMutableSet
 * 无序
 
 3.NSDictionary\NSMutableDictionary
 * 无序
 * 快速创建(不可变):@{key1 : value1,  key2 : value2}
 * 快速访问元素:字典名[key]
 */

#import 

int main()
{
    NSArray *persons = @[
    @{@"name" : @"jack", @"qq" : @"432423423", @"books": @[@"5分钟突破iOS编程", @"5分钟突破android编程"]},
    @{@"name" : @"rose", @"qq" : @"767567"},
    @{@"name" : @"jim", @"qq" : @"423423"},
    @{@"name" : @"jake", @"qq" : @"123123213"}
    ];
    
    // 
    // NSDictionary *jim = persons[2];
    
    
    // 
    NSString *bookName = persons[0][@"books"][1];
    NSLog(@"%@", bookName);
    //NSArray *array = persons[0][@"books"];
    
    //NSLog(@"%@", array);
    
    // 先取出1位置对应的字典
    // 再取出字典中qq这个key对应的数据
    //NSLog(@"%@", persons[1][@"qq"]);
    
    // NSLog(@"%@", jim);
    return 0;
}

void use4()
{
    // 字典不允许有相同的key,但允许有相同的value(Object)
    // 字典的无序的
    NSDictionary *dict = @{
    @"address" : @"北京",
    @"name" : @"jack",
    @"name2" : @"jack",
    @"name3" : @"jack",
    @"qq" : @"7657567765"};
    
    //    NSArray *keys = [dict allKeys];
    //
    //    for (int i = 0; i];
    
    
    NSString *str = dict[@"name"];
    
    
    //NSLog(@"%@", str);
    
    NSLog(@"%@", dict);
    
    
    //NSLog(@"%@", @[@"jack", @"rose"]);
}

void use()
{
    /*
     字典:
     
     key ----> value
     索引 ----> 文字内容
     
     里面存储的东西都是键值对
     
     
     */
    
    // NSDictionary *dict = [NSDictionary dictionaryWithObject:@"jack" forKey:@"name"];
    
    
    // NSArray *keys = @[@"name", @"address"];
    // NSArray *objects = @[@"jack", @"北京"];
    
    // NSDictionary *dict = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
    
    
    /*
     NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
     @"jack", @"name",
     @"北京", @"address",
     @"32423434", @"qq", nil];*/
    
    
    NSDictionary *dict = @{@"name" : @"jack", @"address" : @"北京"};
    
    // id obj = [dict objectForKey:@"name"];
    
    id obj = dict[@"name"];
    
    NSLog(@"%@", obj);
    
    
    
    // 返回的是键值对的个数
    NSLog(@"%ld", dict.count);
}

7.NSNumber

#import 

int main()
{
    // @20  将 20包装成一个NSNumber对像
    
    
    NSArray *array = @[
    
    @{@"name" : @"jack", @"age" : @20},
    
    @{@"name" : @"rose", @"age" : @25},
    
    @{@"name" : @"jim", @"age" : @27}
    ];
    
    
    // 将各种基本数据类型包装成NSNumber对象
    @10.5;
    @YES;
    @'A'; // NSNumber对象
    
    @"A"; // NSString对象
    
    
    
    // 将age变量包装成NSNumber对象
    int age = 100;
    @(age);
    //[NSNumber numberWithInt:age];
    
    
    NSNumber *n = [NSNumber numberWithDouble:10.5];
    
    
    int d = [n doubleValue];
    
    
    
    int a = 20;
    
    // @"20"
    NSString *str = [NSString stringWithFormat:@"%d", a];
    NSLog(@"%d", [str intValue]);
    
    return 0;
}

void test()
{
    NSNumber *num = [NSNumber numberWithInt:10];
    
    NSDictionary *dict =  @{
    @"name" : @"jack",
    
    
    @"age" : num
    
    };
    
    NSNumber *num2 = dict[@"age"];
    
    
    int a = [num2 intValue];
    
    NSLog(@"%d" , a);
}

8.NSDate

#import 

int main()
{
    // 09/10/2011
    NSString *time = @"2011/09/10 18:56";
    
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.dateFormat = @"yyyy/MM/dd HH:mm";
    
    NSDate *date = [formatter dateFromString:time];
    NSLog(@"%@", date);
    return 0;
}


void date2string()
{
    NSDate *date = [NSDate date];
    
    
    // 日期格式化类
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    
    // y 年  M 月  d 日
    // m 分 s 秒  H (24)时  h(12)时
    formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
    
    NSString *str = [formatter stringFromDate:date];
    
    NSLog(@"%@", str);
}

void use()
{
    // 创建一个时间对象
    NSDate *date = [NSDate date];
    // 打印出的时候是0时区的时间(北京-东8区)
    NSLog(@"%@", date);
    
    NSDate *date2 = [NSDate dateWithTimeInterval:5 sinceDate:date];
    
    
    // 从1970开始走过的秒数
    NSTimeInterval seconds = [date2 timeIntervalSince1970];
    
    // [date2 timeIntervalSinceNow];
}

9.NSValue

#import 


// NSNumber之所以能包装基本数据类型为对象,是因为继承了NSValue

int main()
{
    
    // 结构体--->OC对象
    
    CGPoint p = CGPointMake(10, 10);
    // 将结构体转为Value对象
    NSValue *value = [NSValue valueWithPoint:p];
    
    // 将value转为对应的结构体
    // [value pointValue];
    
    NSArray *array = @[value ];
    
    
        // insert code here...
    // NSLog(@"这是哥修改过的东西6");
    return 0;
}

你可能感兴趣的:(Objective-C学习知识点)