【IOS读书笔记】ProgrammingWithObjectiveC 阅读笔记

1. 面向对象I

这里不会像从0开始学OC一样逐步解释面向对象的基本概念,只说一下一些独特之处。

1.1.定义类属性
@property NSString *fullName;

自定义getter名称,自定义只读属性

@property (readonly, getter=isFinished) BOOL finished;

如果执行somePerson.firstName仍然是调用的getter方法

1.2.合成
@implementation YourClass
@synthesize propertyName = instanceVariableName;  //指定为instanceVariableName
或者
@synthesize propertyName  //指定为propertyName
或者不写   //指定为_propertyName
...
@end

此处synthesize的作用只是重新指定名称而已,不加也会有getter setter

1.3.属性配置
@property(nonatomic,retain) UIWindow *window;

其中参数主要分为三个维度,每个维度可以有一个值:

  • 读写属性: (readwrite 默认/readonly)
  • setter语意:(assign/retain/copy) NSFloat,NSInteger只能用assign,否则报错
  • 原子性: (atomic 默认/nonatomic)

强弱:(strong 默认/weak) 强引用、若引用,主要用于arc的垃圾回收,如果一个对象有被强引用则不能被回收。对某一小部分类,如NSTextView无法被申明为weak(历史原因),要用unsafe_unretained关键字代替。
强弱不是一个维度,其本质是setter语意的维度,其中
strong == retain,weak == assign。
验证:如果标示为 (strong, copy)则xcode报错如下:


77BA93B9-3A32-488B-B388-600BA53AA7E9.png

各参数意义如下:

readwrite: 产生setter\getter方法
readonly: 只产生简单的getter,没有setter。
assign: 默认类型,setter方法直接赋值,而不进行retain操作
对基础数据类型 (例如NSInteger,CGFloat)和C数据类型(int, float, double, char, 等) 适用简单数据类型
retain: setter方法对参数进行release旧值,再retain新值。
copy: setter方法进行Copy操作,与retain一样
retain 是指针拷贝,copy 是内容拷贝。
nonatomic: 禁止多线程,变量保护,提高性能

一般使用场景:

//基本属性用assign
@property (assign, nonatomic) NSInteger unit_id;
//类属性用copy
@property (copy,  nonatomic) NSString* name;
//重要的线程安全类
@property (retain,  atomic) ThreadSafeClass* instance;
//待添加
1.4 如何比较两个类
//== 是否指向同一个对象
if (aPerson == bPerson){
}
//isEqual 是否相同
if ([firstPerson isEqual:secondPerson]) {  
    // firstPerson is identical to secondPerson 方法由NSObject提供
}

//比较大小
//the basic Foundation types, like NSNumber, NSString and NSDate, provide a compare: method:
if ([someDate compare:anotherDate] == NSOrderedAscending) {
    // someDate is earlier than anotherDate
}

2.特有语法

简单列举Category, Extension等OC特有的编程结构使用方法

2.1 Category

典型使用场景:

#import "XYZPerson+XYZPersonNameDisplayAdditions.h"
@implementation SomeObject
- (void)someMethod {
    XYZPerson *person = [[XYZPerson alloc] initWithFirstName:@"John" lastName:@"Doe"];
    XYZShoutingPerson *shoutingPerson = [[XYZShoutingPerson alloc] initWithFirstName:@"Monica"
 lastName:@"Robinson"];
    NSLog(@"The two people are %@ and %@",[person lastNameFirstNameString], [shoutingPerson lastNameFirstNameString]);

}
@end

只要import XYZPerson+XYZPersonNameDisplayAdditions.h,就可以在其他的类的实例调用新增方法。
需要注意:category中不能增加property,如果需要,那么要使用继承或者扩展来是实现。

2.2 Extension

中文名:扩展

@interface ClassName ()
@end

扩展即匿名的分类,并且在扩展中可以添加自定义的属性。

3.数据类型

OC中的数据类型主要分为以下几类:

  • C原始类型:
    int float double char
  • OC原始类型:
    NSInteger NSFloat 是int,float的宏定义,做了优化
  • 结构体:
typedef struct {
             int id,
             float height,
             unsigned char flag

}MyTestStruct;

在View框架中能看到大量的常用结构体如CGPoint CGRect CGSize等

  • Foundation对象:
    NSNumber NSString NSRange NSValue
    其中NSValue作用是封装一个结构体,为了给比如NSArray之类的集合类使用,代码如下:
struct MyIntegerFloatStruct aStruct;
aStruct.i = 42;
aStruct.f = 3.14;

NSValue *structValue = [NSValue value:&aStruct
                         withObjCType:@encode(MyIntegerFloatStruct)];
  • enum
    枚举使用的地方都可以用int。而枚举类型常用于有限可选的项,表达更有语义的场景。定义方式如下:


    11919918-3B06-4270-8CB9-7DB3B1A7998B.png

    上述定义自动将第一个值设为0,之后是1,2,3...

4.集合

集合在所有语言的学习中都是重中之重,从数据结构知识中可以知道,无非有这么几种集合:Array, Stack,Queue, Set, Map(Java中认为map不是集合), Tree 等。
Foundation为我们提供了常用的集合实现,主要有:
NSArray, NSSet and NSDictionary.
他们都是不可变对象,相当于Java中的final。如要使用可变对象,都有对应的NSMutableArrayNSMutableDictionary等。

4.1 NSArray

Objective-C的数组比C++,Java的数组强大在于,NSArray保存的对象可以是不同的对象

初始化:
由于 arrayWithObjects: 和 initWithObjects: 方法都采用了以 nil 结束且数量可变的参数,所以您 必须包括 nil 并将其作为最后一个值。

NSArray *someArray =
[NSArray arrayWithObjects:someObject, someString, someNumber, someValue, nil];

这里的对象不能为nil
存在性

if ([someArray containsObject:someString]) 

这个Array相当于java的ArrayList

排序

NSArray *unsortedStrings = @[@"gammaString", @"alphaString", @"betaString"];
NSArray *sortedStrings =
             [unsortedStrings sortedArrayUsingSelector:@selector(compare:)];

默认是immutable
还有NSMutableArray,后者有add,replace,remove功能:

[array addObject:...] : 向可变数组尾部添加数据对象。
[array addObjectsFromArray:..] :向可变数组尾部添加一个数组对象。
[array removeObject:(id)] :删除数组中指定元素,根据对象isEqual消息判断。
[array removeObjectAtIndex:(NSUInteger)]:删除数组中指定脚标索引的数据。
4.2 NSDictionary

只能用NSString作key

//字面量定义(官方推荐使用)
NSDictionary *dictionary = @{
   @"anObject" : someObject,
@"helloString" : @"Hello, World!",
@"magicNumber" : @42,
     @"aValue" : someValue
};
//get方法1
dictionary[@"magicNumber"];
//get方法2
NSNumber *storedNumber = [dictionary objectForKey:@"magicNumber"];
4.3 NSNull

NSNull
是一个工厂类,有方法null

//用于在collection中添加“空”元素。
NSArray *array = @[ @"string", @42, [NSNull null] ];
//判断时采用
if (object == [NSNull null]) {

Tips: nil,Nil,NULL和NSNull 的区别:
从语言角度,NULL是c语言的产物,适用于任何指针
int * pointerA = NULL

OC语言中nil,和Nil代表空指针,即一个目标为空。
nil的目标指实例,如
ClassA * instanceA = nil;
而Nil目标是类
Class* ClassA = Nil;
然而实际上nil和Nil是可以混用的。

NSNull和之前的作用都不同,他是一个真正的类,这个类出现的作用是『标记』

AD15468E-8714-4ED8-B864-06DAA8635A65.png

唯一的类方法是返回一个NSNull的实例,是一个工厂方法。但不是单例工厂。
这个类的实际作用是在NSArray等集合类中占位,代表这个位置为空。因为如果设为nil,在循环的时候就认为集合已经到头了,是无法实现如
*NSArray array = @[ @"string", @42, [NSNull null],@42 ];

这时候判断也要这么进行:
if ([array objectAtIndex:1] == [NSNull null])

4.4 迭代
for (int index = 0; index < count; index++) {

for (id eachObject in array) {
//反向迭代器
for (id eachObject in [array reverseObjectEnumerator]) {

5 Block

总的来说和函数比较像。

  1. 可以实现js中的高阶函数,作为变量传给function
  2. 可以保存和调用block所在域的变量
    下面说说主要的几个用法:

1.用于回调:

//例子1 
//此处就是一个回调函数的用法,使用了block来作为回调传入进去。那为什么不能用另一个函数的@selector?
[task beginTaskWithCallbackBlock:^{
        [self hideProgressIndicator];
}];

//解释:看看task的该方法定义:
- (void)beginTaskWithCallbackBlock:(void (^)(void))callbackBlock;
//是因为从定义上可以更明确(要传入void,void的类型)




//例子2
- (void)doSomethingWithBlock:(void (^)(double, double))block {
    ...
    block(21.0, 2.0);
}

//约定:一般来讲有block参数的函数要把block类型放在最后一个入参,如
- (void)beginTaskWithName:(NSString *)name completion:(void(^)(void))callback;

2.除了回调,还有一个用法是用于迭代,如:

NSArray *array = ...[array enumerateObjectsUsingBlock:^ (id obj, NSUInteger idx, BOOL *stop) {

    NSLog(@"Object at index %lu is %@", idx, obj);
}];
//以及并发版本的迭代:
[array enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^ (id obj, NSUInteger idx, BOOL *stop) {

... }];

3.用于并发任务(Operation Queue \ GCD)

// Operation Queue
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
    ...
}];
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
[mainQueue addOperation:operation];

//GCD:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{ NSLog(@"Block for asynchronous execution");

});
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,776评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,527评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,361评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,430评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,511评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,544评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,561评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,315评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,763评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,070评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,235评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,911评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,554评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,173评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,424评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,106评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,103评论 2 352

推荐阅读更多精彩内容