一些知识点

2017-06-27  本文已影响0人  Alfred的记录本

1.

clipsToBounds:是指视图上的子视图,如果超出父视图的部分就截取掉,
masksToBounds:是指视图的图层上的子图层,如果超出父图层的部分就截取掉

2.

// NSArray --> NSMutableArray  
NSMutableArray *myMutableArray = [myArray mutableCopy];  
  
// NSMutableArray --> NSArray  
NSArray *myArray = [myMutableArray copy];

3.

1.自定义cell时,
若使用nib,使用 registerNib: 注册,dequeue时会调用 cell 的 -
(void)awakeFromNib
不使用nib,使用 registerClass: 注册, dequeue时会调用 cell 的 - (id)initWithStyle:withReuseableCellIdentifier:
2.需不需要注册?
使用dequeueReuseableCellWithIdentifier:可不注册,但是必须对获取回来的cell进行判断是否为空,若空则手动创建新的cell;
使用dequeueReuseableCellWithIdentifier:forIndexPath:必须注册,但返回的cell可省略空值判断的步骤。

4.

如果该类没有ViewController

[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];

5.字典和实体类的转换

[self setValuesForKeysWithDictionary:dict];

6.delegate block属性的关键字

7.隐藏UITableBar

当页面使用 UITabBarController + UINavigationController 框架的时候,当跳转到详情页面的时候,如果 UITabBar 仍然存在的话就会造成逻辑混乱,用户体验也会下降,因此我们就有一个在详情页将 UITabBar 隐藏的需求,参考链接

8. id的使用

id <SDWebImageOperation> operation

9. runtime动态添加属性

10. 自定义NSOperation

11.NSURLSession

12.KVO KVC

    [self willChangeValueForKey:@"changeHeight"];
    _changeHeight = self.frame.size.height;
    [self didChangeValueForKey:@"changeHeight"];
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)theKey {
    if ([theKey isEqualToString:@"changeHeight"]) {
        return NO;
    } else {
        return [super automaticallyNotifiesObserversForKey:theKey];
    }
}

13.HTTPS 验证

14.网络缓存

网络缓存

15.NSURLCache

参考链接

16.extern const static

参考链接

#import "a.h"
NSString * const strExtern = @"strExtern";
#import "a.h"
NSLog(@"strExtern : %@", strExtern);
NSString * const strExtern = @"strExtern";//指针指向的地址(strExtern)不可变
const NSString *strExtern = @"strExtern";//字符串内容(*strExtern)不可变
static NSString * const strExtern = @"strExtern";

16. __nullable和 __nonnull

苹果在Xcode 6.3引入了一个Objective-C的新特性:nullability annotations。这一新特性的核心是两个新的类型注释:__nullable和__nonnull。从字面上我们可以猜到,__nullable表示对象可以是NULL或nil,而__nonnull表示对象不应该为空。当我们不遵循这一规则时,编译器就会给出警告。

17. delegate block 的修饰符

18. block 引起的循环引用

某个类将block作为自己的属性变量,然后该类在block的方法体里面又使用了该类本身,即使在你的block代码中没有显式地出现"self",也会出现循环引用!只要你在block里用到了self所拥有的东西!简单说就是

self.someBlock = ^(Type var){
  [self dosomething];
  或者self.otherVar = XXX;
  或者_otherVar = ...
}
__weak typeof(self) weakSelf = self;
self.blkA = ^{
__strong typeof(weakSelf) strongSelf = weakSelf;//加一下强引用,避免weakSelf被释放掉
NSLog(@"%@", strongSelf->_xxView); //不会导致循环引用.
};

分两种环境去解决:
1)ARC环境下:ARC环境下可以通过使用_weak声明一个代替self的新变量代替原先的self,我们可以命名为weakSelf。通过这种方式告诉block,不要在block内部对self进行强制strong引用:(如果要兼容ios4.3,则用__unsafe_unretained代替__weak,不过目前基本不需考虑这么low的版本)

          self.arr = @[@111, @222, @333];
         __weak typeof(self) weakSelf=self;
         self.block = ^(NSString *name){
             NSLog(@"arr:%@", weakSelf.arr);
         };

2)MRC环境下:解决方式与上述基本一致,只不过将__weak关键字换成__block即可,这样的意思是告诉block:小子,不要在内部对self进行retain了!

19.id数据类型与静态类型

  • 虽然说id数据类型可以存储任何类型的对象,但是不要养成滥用这种通用类型
  • 动态类型判断类型

20.分类(category)和类扩展(extension)

- (void)setName:(NSString *)name
{
    objc_setAssociatedObject(self,
                             "name",
                             name,
                             OBJC_ASSOCIATION_COPY);
}

- (NSString*)name
{
    NSString *nameObject = objc_getAssociatedObject(self, "name");
    return nameObject;
}

21.协议

协议中能够声明方法,以及属性。然后问题就来了,不是不能定义成员变量的吗?

对,的确不能定义成员变量,但是属性是什么?属性包含了三个东西:成员变量、setter方法、getter方法。在类中定义的属性,当然三者都有,然而协议中定义的属性只有获取和设置方法,没有成员变量,这就要求该协议的遵守者必须自己写出setter和getter方法的实现。但是有一种情况是不需要的,那就是遵守者本来就有这个属性,此时系统会为这个属性自动生成设置获取方法,既然已经实现了,那么遵守者就没必要去实现协议中的这个属性了。

尽管可以实现“伪属性”,但是,我们还是应该尽量把属性定义在主接口中,而不应该定义在协议中。

22.断言

- (void)printMyName:(NSString *)myName  
{  
    NSAssert(myName != nil, @"名字不能为空!");  
    NSLog(@"My name is %@.",myName);  
} 

当传给函数的参数(myName)为空时,断言将被执行,程序Crash,并打印出断言中的描述信息。本例中,在控制台打印出了如下的日志:

NSAssert[1268:a0b] *** Assertion failure in -[ViewController printMyName:]  
NSAssert/NSAssert/ViewController.m:38
2013-11-21 13:56:01.927 NSAssert[1268:a0b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '名字不能为空!'

开发者没有必要在应用程序的每个版本中都进行断言检查,这是因为大多数项目都是有两个版本:Debug版和Release版。在Debug版中,开发者希望所有的断言都检查到,而在Release版中,往往都是禁用断言检查的。设置Release版本中禁用断言的方法如下:
在Build Settings菜单,找到Preprocessor Macros项,Preprocessor Macros项下面有一个选择,用于程序生成配置:Debug版和Release版。选择 Release项,设置NS_BLOCK_ASSERTIONS,不进行断言检查。

23.dispatch_barrier_sync和dispatch_barrier_async

共同点:
1、等待在它前面插入队列的任务先执行完
2、等待他们自己的任务执行完再执行后面的任务

不同点:
1、dispatch_barrier_sync将自己的任务插入到队列的时候,需要等待自己的任务结束之后才会继续插入被写在它后面的任务,然后执行它们
2、dispatch_barrier_async将自己的任务插入到队列之后,不会等待自己的任务结束,它会继续把后面的任务插入到队列,然后等待自己的任务结束后才执行后面任务。

24.NSObject + (void)load

25.__attribute__

参考链接

26.__IPHONE_OS_VERSION_MAX_ALLOWED __IPHONE_OS_VERSION_MIN_REQUIRED

这些编译期常量, 对运行时的环境判断完全无效, 它告诉编译器用哪一段代码来进行编译, 那那段代码里, 你仍然可以写运行到目标机器里会崩溃的代码

怎么解决? 组合!

  1. 我先判断编译环境, 以避免低版本SDK不认识高版本SDK的api, 造成编译错误(片段1)
  2. 在高版本SDK的条件内, 自行开始判断SDK版本, 或responedToSelector都可以,来判断是否使用高版本的api
  3. 在低版本条件内, 直接用低版本的api

27. NSRunLoop

28. get 请求重定向

(nullable NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(nullable NSURLResponse *)response
(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
willPerformHTTPRedirection:(NSHTTPURLResponse *)response
        newRequest:(NSURLRequest *)request
 completionHandler:(void (^)(NSURLRequest * __nullable))

29.接口函数过期提醒

使用时xcode会提示‘showWithMaskType’ is deprecated:Use show and setDefaultMaskType: instead.

+ (void)showWithMaskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use show and setDefaultMaskType: instead.")));

30 +load,constructor,main的执行顺序

+ (void)load{
    NSLog(@"load");
}
__attribute__((constructor))
void  constr(){
    NSLog(@"before main");
}

输出结果如下:
2016-07-21 22:13:58.591 Study[14185:5421811] load
2016-07-21 22:13:58.592 Study[14185:5421811] before main
2016-07-21 22:13:58.592 Study[14185:5421811] main

31. NSURLProtocol

@interface CustomURLProtocol : NSURLProtocol
@end
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //注册protocol
    [NSURLProtocol registerClass:[CustomURLProtocol class]];
    return YES;
}

32. NSURLSessionConfiguration

33.FOUNDATION_EXPORT 与#define

34. Keychain

35. CoreText

36. NSUserDefaults

37. WindowLevel

1)当Level层级相同的时候,只有第一个设置为KeyWindow的显示出来,后面同级的再设置KeyWindow也不会显示。
2)statusLevelWindow在alertLevelWindow之后调用makeKeyAndVisible,仍然只是显示在alertLevelWindow的下方。这说明UIWindow在显示的时候是不管KeyWindow是谁,都是Level优先的,即Level最高的始终显示在最前面。

38.@synchronized

39.UIView setFrame方法

40.UIView的生命周期

41.delegate 作为属性需要使用weak

delegate作为属性需要是weak?
防止retain cycle循环引用...

比如tableview....UIViewCotroller通过self.view addsubview.已经指向tableview了......所以tableview.delegate = self 和tableview.datasource又指向了viewcontroller,如果此时delegate是strong,就会发生循环引用无法释放,所以这里应该是weak.....

42.readonly

43.__unsafe_unretained

44.UIScrollView下沉64像素

在ViewController中
self.edgesForExtendedLayout = UIRectEdgeNone;

self.automaticallyAdjustsScrollViewInsets = NO;

45.bounds与frame的区别

区别

46.获取字符串宽度

[self.titleLabel.text sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]}].width]

47.约束

mas_makeConstraints && mas_remakeConstraints && mas_updateConstraints

48.谓词(NSPredicate)

49.ViewController 和 xib关联

1、新建xxViewController 和 xib(xib 文件名与vc相同) ,并且设置xib 的 file’s owner 为xxViewController,
2、Outlets中的view 跟xib中的view做关联,如果没有这一步会报“loaded the "xxxView" nib but the view outlet was not set.”

第一种方法:
CustomViewController* customViewController = [[CustomViewController alloc] initWithNibName:nil bundle:nil];
你可以看现第一个传数是nil, 对没错,传nil也是可以的。因为如果系统发现是nil的话,会在工程的bundle里找与CustomViewController同名的xib文件,因为模版生成的正好名字相同,所以能够正确加载xib文件。
第二种方法:
CustomViewController* customViewController = [[CustomViewController alloc] init];
在这儿我们只是简单的初始化,也能正解加载相应的xib文件,因为他们名字是相同的。
如果xib的名了与类的名字不同呢?
如果不同那么我们就不能用上面的两种方法,必须显示指明xib的名字,如:
CustomViewController* customViewController = [[CustomViewController alloc] initWithNibName:"firstView" bundle:nil]
在这儿我们显示指明是firstView.xib这个文件。

50.枚举

NS_ENUM定义通用枚举,NS_ENUM定义的枚举不能几个枚举项同时存在,只能选择其中一项,

typedef NS_ENUM(NSInteger, SDWebImageDownloaderExecutionOrder) {
    SDWebImageDownloaderFIFOExecutionOrder,
    SDWebImageDownloaderLIFOExecutionOrder
};

NS_OPTIONS定义位移枚举

typedef NS_OPTIONS(NSUInteger, SDWebImageDownloaderOptions) {
    SDWebImageDownloaderLowPriority = 1 << 0,
    SDWebImageDownloaderProgressiveDownload = 1 << 1,
    SDWebImageDownloaderUseNSURLCache = 1 << 2,
    SDWebImageDownloaderIgnoreCachedResponse = 1 << 3,
};

位移枚举即是在你需要的地方可以同时存在多个枚举值如这样:

SDWebImageDownloaderOptions opt = SDWebImageDownloaderLowPriority | SDWebImageDownloaderIgnoreCachedResponse;

判断的时候是这样

if (options & SDWebImageDownloaderUseNSURLCache){}

51.多线程中的数据同步

52. initialize load

+(void)load 在程序运行后立即执行
+(void)initialize 在类的方法第一次被调时执行

53.__block与__weak区别

54. performSelector调用和直接调用区别

55.@autoreleasepool

当需要在程序中创建大量的临时变量时(大量也可指数量多,不确定,比如从数据库中读取数据时),很容易使内存产生峰值又回到内存低谷,这样对程序的性能会产生很大影响,而使用自动释放池后,峰值明显有所下降。
官方提出的解决方案是,在大量产生局部变量的位置用autoreleasepool代码块进行包装。比如for循环中要执行的语句,这样每次for循环结束后就会及时收回临时变量占用的内存空间。

for (int i = 0; i < 10e6; ++i) {
        @autoreleasepool {
        NSString *str = [NSString stringWithFormat:@"hi + %d", i];
        [collection addObject:str];
        }
    }

56.加载图片的两种方式

-imageNamed: 是读取到内存后会缓存下来,下次再读取时直接从缓存中获取,因此访问效率要比较高。对于图片资源比较小,使用比较频繁的图片,通常会选择使用此种方式来加载。当然,若不需要考虑性能时,直接使用此种方式也是可以的。
-initWithContentsOfFile: 当图片资源比较大,或者图片资源只使用一次就不再使用了,那么使用此种方式是最佳方式。当应用程序需要加载一张比较大的图片并且是一次性使用的,那么是没有必要去缓存这个图片的,用-imageWithContentsOfFile:是最为经济的方式,这样不会因为UIImage元素较多情况下,CPU会被逐个分散在不必要的缓存上而浪费过多CPU时间。另外,当我们的图片不是PNG图片时,我们通常会选择此种方式来加载。
SDWebImageDecoder引发的思考

57.NSData

58.NSCoding

59.属性修饰符

60.导航栏遮挡view问题

if (kCurrentFloatDevice > 7.0) {
        self.edgesForExtendedLayout = UIRectEdgeNone;
    }

61.NSException

62.NSError

63.方法中的数据传递和值传递

64. NSSortDescriptor

65. NSIndexSet

66. edgesForExtendedLayout

edgesForExtendedLayout浅淡,
edgesForExtendedLayout

上一篇 下一篇

猜你喜欢

热点阅读