程序员iOS零碎知识

【IOS读书笔记】ProgrammingWithObjectiv

2016-04-26  本文已影响111人  纳达丶无忌

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;

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

强弱:(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中的数据类型主要分为以下几类:

typedef struct {
             int id,
             float height,
             unsigned char flag

}MyTestStruct;

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

struct MyIntegerFloatStruct aStruct;
aStruct.i = 42;
aStruct.f = 3.14;

NSValue *structValue = [NSValue value:&aStruct
                         withObjCType:@encode(MyIntegerFloatStruct)];

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");

});
上一篇下一篇

猜你喜欢

热点阅读