OC笔记 3年前的

1  内存管理原则   只要出现new   alloc   retain  配对出现release     kvc  kvo监听属性  有人改了  它也改

2 set方法    if(_xx!= xx) {  _xx release;   _xx = xx retain }        dealloc { _ xx  release  }

3  property参数       1 set方法参数   retain (对象类型  符合内存管理规则)        assign(直接赋值  )     2  nonatomic(线程相关)   copy(NSString)     3是否生成set get readonly    4  set get方法别名     5 ARC 对象类型   strong替代retain   weak替代assign     基本类型手机和ARC是一样  6 arc   copy nsstring  block   ,weak  代理 控件,strong 对象 ,assign 基本数据   7 NSMutableDictionary *dict = [NSMutableDictionary dictionary];[dict setObject:@"母鸡" forKey:@"name"];dict[xx]= xxx 

4  autoreleasepool  需要调用 对象autoralease     ,autoreleasepool   里面调用几次对象的autoralease     就会调用几次。

5  指向函数的指针void test{}
  void (*mypoint)() = test
   mypoint()
 OC block  void(^myblock) = ^ {}
   myblock()

   int (^sumBlock)(int ,int) =  ^(int a, int b){
            return  a + b;
        };

int  a=sumBlock(1,1);    快捷键inlineblock

6 tableviewcell    有个contentView     其他控件都在contentview里面     内边距uibutton.contentEdgeInsets = UIEdgeInsetsMake

在UITextField左边放一个view
self.textField.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 8, 0)];
self.textField.leftViewMode = UITextFieldViewModeAlways;

// 在UITextField设置键盘右下角按钮的样式
        self.returnKeyType = UIReturnKeySearch;
        self.enablesReturnKeyAutomatically = YES;

7  两个uisrcolerview   必须使用nsrunloop 

 

8  nstimer cadisplaylink

 

9   3.动画 [UIView animateWithDuration

 

10  [self performSelector:@selector(nextQuestion) withObject:nil afterDelay:0.5];

 

11  heightForRowAtIndexPath      self.tableView.rowHeight = 60;

12自定义 uitableViewcell    变量名字不要定义imageview  ,系统uitableviewcell 有这个名字。

// 设置选中时的背景 
    uitableviewcell .selectedBackgroundView = selectedBg;

13  uitableviewcell   tablefooterview只需要设置高度    宽XY等设置也没有用.- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 1.取消选中这行
    [tableView deselectRowAtIndexPath:indexPath animated:YES];}

 

14  UINib  nibwithNibName           ;nib   instantiatewithOwer    lastobject;;;;   UITableViewcell = [[[NSBundle mainBundle] loadNibNamed:@"MJTgCell" owner:nil options:nil] lastObject];;;;

+ (instancetype)headerView
{
     return [[[NSBundle mainBundle] loadNibNamed:@"MJTgHeaderView" owner:nil options:nil] lastObject];
//    headerView.scrollView
}

+ (instancetype)cellWithTableView:(UITableView *)tableView
{
    static NSString *ID = @"tg";
    MJTgCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        // 从xib中加载cell
        cell = [[[NSBundle mainBundle] loadNibNamed:@"MJTgCell" owner:nil options:nil] lastObject];
    }

cell .accessType = 箭头
    return cell;
}

15   // 模拟(2秒后执行跳转)
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        // 移除遮盖
        [MBProgressHUD hideHUD];
        
        // 跳转 -- 执行login2contacts这个segue
        [self performSegueWithIdentifier:@"login2contacts" sender:nil];
    });

16 uiview  init方法通过代码new对象才会调用 ,awakeFromNib  通过xib创建对象会调用。

 

17 代码创建uitableviewcell  ,需要重写initwithstyle   ,在这个方法里面创建其他控件,代码创建uitabviewcontroller  initwithstyle   方法设置单租 和分组模式

 uitableviewcell   cell = [[uitableviewcell  alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];

 

18  beakgroundview优先级大于backgroundcolor

19 viewcontroller  endEditing   resignFirstResponder   ;;   self.tableView.allowsSelection = NO; // 不允许选中       

20  静态uitableview     设置多行的时候会复制第一个

 

21 任何控件初始化宽高都是0  ,在uiview   layoutsubviews设置,当frame改变时候调用    不要在初始化方法里面设置frame.在layoutsubviews设置frame

 

22 UIView/**
 *  当一个控件被添加到父控件中就会调用  tableview  QQ好友展开合并  headerview设置旋转就在这设置.
 */
- (void)didMoveToSuperview

 

23 UIbutton 里面的imageview      // 设置按钮内部的imageView的内容模式为居中
        nameView.imageView.contentMode = UIViewContentModeCenter;
        // 超出边框的内容不需要裁剪
        nameView.imageView.clipsToBounds = NO;

 

24 代码设置按钮点击事件  [nameView addTarget:self action:@selector(nameViewClick) forControlEvents:UIControlEventTouchUpInside];

 

25  应用管理 点击下载的时候    中间弄个提示 已经下载

 // 1.添加标签
    UILabel *label = [[UILabel alloc] init];
    label.text = [NSString stringWithFormat:@"成功下载%@", cell.app.name];
    label.font = [UIFont systemFontOfSize:12];
    label.textAlignment = NSTextAlignmentCenter;
    label.textColor = [UIColor whiteColor];
    label.backgroundColor = [UIColor blackColor];
    label.frame = CGRectMake(0, 0, 150, 25);
    label.center = CGPointMake(160, 240);
    label.alpha = 0.0;
    label.layer.cornerRadius = 5;
    label.clipsToBounds = YES;
    [self.view addSubview:label];
    
    // 2.动画
    [UIView animateWithDuration:0.5 animations:^{
        label.alpha = 0.5;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.5 delay:0.5 options:UIViewAnimationOptionCurveLinear animations:^{
            label.alpha = 0.0;
        } completion:^(BOOL finished) {
            [label removeFromSuperview];
        }];
    }];

app.networkActivityIndicatorVisible = YES;

26  uitextField调出时间控件     uitextfield.inputview =  uidatepicker;    uitextfield.inputaccessoryview可以在键盘上自定义一个view

 

27 toolbar里面只能放UIBarButtonItem 控件 ,可以设置barbuttonitem是弹簧   barbuttonitem里面可以放其它控件比如uibutton。

直接拖uibutton,他自己会自动弄到uibarbuttonitem里面。uibarbuttonitem中间的view可以放按钮,也可以直接是写文字.

28 状态栏默认是viewcontroller管理,如果要uiappcation管理  要设置info.plist

29uiviewcontroller 实现了loadview方法  会跳过加载stroyborad或者xib.         

 UIStoryboard *story = [UIStoryboard storyboardWithName:@"Test" bundle:nil];
self.window.rootViewController = [story instantiateInitialViewController];

self.window.rootViewController = [[MJViewController alloc] initWithNibName:@"MJViewController" bundle:nil];

 

30   控制器的view是全屏的包括状态栏  

自动型Segue    使用push方法能将某个控制器压入栈
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
使用pop方法可以移除控制器
将栈顶的控制器移除
- (UIViewController *)popViewControllerAnimated:(BOOL)animated;
回到指定的子控制器
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;
回到根控制器(栈底控制器)
- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated;

手动型的Segue需要设置一个标识
在恰当的时刻,使用perform方法执行对应的Segue
[self performSegueWithIdentifier:@"login2contacts" sender:nil];调用sourceViewController的下面方法,做一些跳转前的准备工作并且传入创建好的Segue对象- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;

---------

除了push之外,还有另外一种控制器的切换方式,那就是Modal  ,modal的rootviewcontroller一直都是第一个.其他的用presentedviewcontroller引用
任何控制器都能通过Modal的形式展示出来
Modal的默认效果:新控制器从屏幕的最底部往上钻,直到盖住之前的控制器为止
以Modal的形式展示控制器
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion
关闭当初Modal出来的控制器
- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion;(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;

 

31 导航栏的内容由栈顶控制器的navigationItem属性决定   ,navigationItem里面左右两边只能放UIBarButtonItem 控件 ,可以设置barbuttonitem是弹簧   barbuttonitem可以放其它控件比如uibutton

 

33 Documents:保 iTunes同步设备时会备份该目录。例如,游戏应用可将游戏存档保存在该目录
tmp:保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也可能会清除该目录下的文件。iTunes同步设备时不会备份该目录
Library/Caches: iTunes同步设备时不会备份该目录。一般存储体积大、不需要备份的非重要数据
Library/Preference:保存应用的所有偏好设置,iOS的Settings(设置)应用会在该目录中查找应用的设置信息。iTunes同步设备时会备份该目录

34  如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,就可以使用writeToFile:atomically:方法直接将对象写到属性列表文件中

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];[defaults setObject:@"itcast" forKey:@"username"],[defaults synchornize];;NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];NSString *username = [defaults stringForKey:@"username"];

归档(编码)[NSKeyedArchiver archiveRootObject:person toFile:path];
恢复(解码)Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

 数组 NSMutableArray *contacts=[NSKeyedUnarchiver unarchiveObjectWithFile:MJContactsFilepath]

 

// 将数据封装成字典

NSMutableDictionary *dict = [NSMutableDictionary dictionary];

[dict setObject:@"母鸡" forKey:@"name"];

[dict setObject:@"15013141314" forKey:@"phone"];

[dict setObject:@"27" forKey:@"age"];

// 将字典持久化到Documents/stu.plist文件中

[dict writeToFile:path atomically:YES];

// 读取Documents/stu.plist的内容,实例化NSDictionary

NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];

NSLog(@"name:%@", [dict objectForKey:@"name"]);

NSLog(@"phone:%@", [dict objectForKey:@"phone"]);

NSLog(@"age:%@", [dict objectForKey:@"age"]);

 

 

35 如果UITabBarController有N个子控制器,那么UITabBar内部就会有N个UITabBarButton作为子控件    UITabBarButton里面显示什么内容,由对应子控制器的tabBarItem属性决定.

 

UITabBarItem有以下属性影响着UITabBarButton的内容
标题文字 @property(nonatomic,copy) NSString *title; 
图标
@property(nonatomic,retain) UIImage *image; 
选中时的图标
@property(nonatomic,retain) UIImage *selectedImage; 
提醒数字
@property(nonatomic,copy) NSString *badgeValue;

[[UIImage imageNamed:selectedImageName] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];告诉系统用原始图片

UITabBar里面放UITarBarButton是私有的,UITarBarButton是UIControl的子类

36//app进入后台:休眠,  不能接受事情(比如关闭)  ,接受事情必须mp3应用
/**
 *  app关闭的时候调用(一般情况下不会调用)
 */
- (void)applicationWillTerminate:(UIApplication *)application

 

37  隐藏uitabbar  勾选hide bottom bar on push.  uitabviewcontroller-storyborad使用静态单元格uitabviewcontroller类里面必须删除两个代理方法(return行和组的).

hidesBottomBarWhenPushed

38 获得图形上下文
CGContextRef ctx = UIGraphicsGetCurrentContext(); 
拼接路径(下面代码是搞一条线段)
CGContextMoveToPoint(ctx, 10, 10);
CGContextAddLineToPoint(ctx, 100, 100);
CGContextSetLineWidth( 100);
CGContextSetLinecap
CGContextSetLineJoin
CGContextSetRGB==UICORLOR  WITHER  SET
CGContextStrokePath(ctx);绘制路径
CGContextMoveToPoint(ctx, 10, 10);
CGContextAddLineToPoint(ctx, 100, 100);
CGContextSetLineWidth( 100);
CGContextSetRGB
绘制路径
CGContextStrokePath(ctx); // CGContextFillPath(ctx);

-----添加一个矩形
void CGContextAddRect(CGContextRef c, CGRect rect) 
添加一个椭圆
void CGContextAddEllipseInRect(CGContextRef context, CGRect rect) 
添加一个圆弧
void CGContextAddArc(CGContextRef c, CGFloat x, CGFloat y,
  CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise)

// 关闭路径(连接起点和最后一个点)
    CGContextClosePath(ctx);

39 设置view背景    view.backcolor = UIColor colorWithPatternImage把图片转换成颜色   ui控件 init方法默认调用initwithframe    ,initwithframe    代码创建控件调用

 // 设置全局导航栏主题    导航栏高度64  ios6导航栏高度44

/**initailize、load方法的区别
initailize、load都是类方法
当一个类被装载进内存时,就会调用一次load方法(当时这个类还不可用)
当第一次使用这个类时,就会调用一次initailize方法
 *  系统在第一次使用这个类的时候调用(1个类只会调用一次)
 */
+ (void)initialize
    UINavigationBar *navBar = [UINavigationBar appearance];
    [navBar setBackgroundImage:[UIImage imageNamed:bgName] forBarMetrics:UIBarMetricsDefault];// 设置标题文字颜色
    NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
    attrs[UITextAttributeTextColor] = [UIColor whiteColor];
    attrs[UITextAttributeFont] = [UIFont systemFontOfSize:16];
    [navBar setTitleTextAttributes:attrs];

// 设置全局状态栏的样式
    application.statusBarStyle = UIStatusBarStyleLightContent;

导航栏文字阴影  textAttrs[UITextAttributeTextShadowOffset] = [NSValue valueWithUIOffset:UIOffsetZero];

 

40 appicon去掉反光效果  点击 appicon   勾选ios icon is pre_render    2程序启动时隐藏状态栏  勾选Hide  during  application  lunch   然在appDelegate   application.statusBarHide=no

41自定义uibutton   从文件中解析一个对象的时候就会调用这个方法 . 方法执行顺序 initWithCoder-titleRectForContentRect-awakeFromNib

42 image拉伸storyborad上的stretching      uibuttonstoryborad上的stretching 只对uibutton里面的Image有用 ,

stretchableImageWithLeftCapWidth 图片拉伸,    两个resizableImageWithCapInsets方法 重写了一个.

+ (UIImage *)resizedImageWithName:(NSString *)name
{
    return [self resizedImageWithName:name left:0.5 top:0.5];
}


+ (UIImage *)resizedImageWithName:(NSString *)name left:(CGFloat)left top:(CGFloat)top
{
    UIImage *image = [self imageWithName:name];
    return [image stretchableImageWithLeftCapWidth:image.size.width * left topCapHeight:image.size.height * top];
}

43   设置BarButtonItem的主题

    UIBarButtonItem *item = [UIBarButtonItem appearance]; 

navBar.tintcolor = [uicolor  redcolor]//返回按钮的那个箭括号的颜色

    // 设置文字颜色
    NSMutableDictionary *itemAttrs = [NSMutableDictionary dictionary];
    itemAttrs[NSForegroundColorAttributeName] = [UIColor whiteColor];
    itemAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:14];
    [item setTitleTextAttributes:itemAttrs forState:UIControlStateNormal];

 

45 在model模型数据中UI控件用strong, UITableViewCell accessoryView使用strong  ,[UITableViewCell .contentView addSubview:divider]  divider使用weak
 

46  UICollectionViewController   必须在viewDidLoad      // 1.注册cell(告诉collectionView将来创建怎样的cell)
    UINib *nib = [UINib nibWithNibName:@"MJProductCell" bundle:nil];
    [self.collectionView registerNib:nib forCellWithReuseIdentifier:MJProductCellID];
//    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:MJProductCellID];
    // 2.设置collectionView的背景色
    self.collectionView.backgroundColor = [UIColor whiteColor];

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    // 1.获得cell
    MJProductCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:MJProductCellID forIndexPath:indexPath];
    // 2.传递模型
    cell.product = self.products[indexPath.item];
    return cell;
}

- (id)init
{
    // 1.流水布局
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    // 2.每个cell的尺寸
    layout.itemSize = CGSizeMake(80, 80);
    // 3.设置cell之间的水平间距
    layout.minimumInteritemSpacing = 0;
    // 4.设置cell之间的垂直间距
    layout.minimumLineSpacing = 10;
    // 5.设置四周的内边距
    layout.sectionInset = UIEdgeInsetsMake(layout.minimumLineSpacing, 0, 0, 0);
    return [super initWithCollectionViewLayout:layout];
}

47 // JSON文件的路径
        NSString *path = [[NSBundle mainBundle] pathForResource:@"products.json" ofType:nil];
        
        // 加载JSON文件
        NSData *data = [NSData dataWithContentsOfFile:path];
        
        // 将JSON数据转为NSArray或者NSDictionary
        NSArray *dictArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];

48  imageview圆角 // 根据图片自动调整大小
    [self.imageView sizeToFit];

    self.iconView.layer.cornerRadius = 8;
    self.iconView.clipsToBounds = YES;

49 真机调式  需要加入99美元年费账号

登录开发者主页
生成cer证书:cer是一个跟电脑相关联的证书文件,让电脑具备真机调试的功能  :只能配置一台电脑  可以删除 然后增加
添加App ID:调试哪些app?
注册真机设备:哪台设备需要做真机调试?
生成MobileProvision文件:结合2、3、4生成一个手机规定文件
导入cer、MobileProvision文件

50 打开别的应用,别的应用需要配置 URL types : url identifier  URL Schemes

 51  ViewController 里面的block    __unsafe_unretained  ViewController *share = self;

__unsafe_unretained typeof(self) selfVc = self;

52 /** 
     UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,  距离父控件左边的间距是伸缩的
     UIViewAutoresizingFlexibleWidth        = 1 << 1,  自己的宽度跟随着父控件的宽度进行伸缩
     UIViewAutoresizingFlexibleRightMargin  = 1 << 2,  距离父控件右边的间距是伸缩的
     UIViewAutoresizingFlexibleTopMargin    = 1 << 3,  距离父控件顶部的间距是伸缩的
     UIViewAutoresizingFlexibleHeight       = 1 << 4,  自己的高度跟随着父控件的高度进行伸缩
     UIViewAutoresizingFlexibleBottomMargin = 1 << 5   距离父控件底部的间距是伸缩的
     */
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeContactAdd];
    btn.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

53 // 2.保存到图片
    UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);

54 // 设置按钮不可用
    self.userInteractionEnabled = NO;

55 多个手势需要实现代理方法

shouldRecognizeSimultaneouslyWithGestureRecognizer

56 calayer     self.iconView.layer.transform = CATransform3DMakeRotation(M_PI_4, 0, 0, 1); 
    NSValue *value = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_4, 0, 0, 1)];
    [self.iconView.layer setValue:value forKeyPath:@"transform"]; 
    [self.iconView.layer setValue:@(M_PI_2) forKeyPath:@"transform.rotation"];可以传递哪些key path, 在官方文档搜索"CATransform3D key paths"

CALayer是定义在QuartzCore框架中的
CGImageRef、CGColorRef两种数据类型是定义在CoreGraphics框架中的
UIColor、UIImage是定义在UIKit框架中的  QuartzCore框架和CoreGraphics框架是可以跨平台使用的,在iOS和Mac OS X上都能使用

57 calayer隐式动画//    [CATransaction begin]; // 开启事务
//    [CATransaction setDisableActions:YES]; 
//    self.layer.position = CGPointMake(100, 100);  
//    [CATransaction commit]; // 提交事务

58    CAKeyframeAnimation *anim = [CAKeyframeAnimation animation]; calayer动画一般只用转场动画  因为他的动画不改变位置等.一般用uiview动画
    anim.keyPath = @"position";
    anim.removedOnCompletion = NO;
    anim.fillMode = kCAFillModeForwards;
    anim.duration = 2.0; [self.redView.layer addAnimation:anim forKey:nil];

  围绕圆转圈动画 

    CAKeyframeAnimation *anim = [CAKeyframeAnimation animation]; 
    anim.keyPath = @"position";
    anim.removedOnCompletion = NO;
    anim.fillMode = kCAFillModeForwards;
    anim.duration = 2.0; 
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddEllipseInRect(path, NULL, CGRectMake(100, 100, 200, 200));
    anim.path = path;
    CGPathRelease(path); 
    // 设置动画的执行节奏
    // kCAMediaTimingFunctionEaseInEaseOut : 一开始比较慢, 中间会加速,  临近结束的时候, 会变慢
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    anim.delegate = self; 
    [self.redView.layer addAnimation:anim forKey:nil];

59

/* 过渡效果 fade     //交叉淡化过渡(不支持过渡方向) kCATransitionFade push     //新视图把旧视图推出去  kCATransitionPush
 moveIn   //新视图移到旧视图上面   kCATransitionMoveIn reveal   //将旧视图移开,显示下面的新视图  kCATransitionReveal cube     //立方体翻滚效果 oglFlip  //上下左右翻转效果 suckEffect   //收缩效果,如一块布被抽走(不支持过渡方向) rippleEffect //滴水效果(不支持过渡方向) pageCurl     //向上翻页效果 pageUnCurl   //向下翻页效果 cameraIrisHollowOpen  //相机镜头打开效果(不支持过渡方向) cameraIrisHollowClose //相机镜头关上效果(不支持过渡方向) */  

 

 /* 过渡方向 kCATransitionFromRight kCATransitionFromLeft kCATransitionFromBottom kCATransitionFromTop*/


CATransition的使用
CATransition *anim = [CATransition animation];
anim.type = @“cube”; // 动画过渡类型
anim.subtype = kCATransitionFromTop; // 动画过渡方向
anim.duration = 1; // 动画持续1s
// 代理,动画执行完毕后会调用delegate的animationDidStop:finished:
anim.delegate = self;
/*******中间穿插改变layer属性的代码**********/   
[layer addAnimation:anim forKey:nil];

 

60 uiview动画

[UIView beginAnimations:nil context:nil];
    // 动画执行完毕后, 会自动调用self的animateStop方法
    //    [UIView setAnimationDelegate:self];
    //    [UIView setAnimationDidStopSelector:@selector(animateStop)];
    self.myview.center = CGPointMake(200, 300);
    [UIView commitAnimations];

61 用CADisplayLink做转圈动画

// 1秒内刷新60次
    CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(update)];
    [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    self.link = link;- (void)update
{
    self.centerWheel.transform = CGAffineTransformRotate(self.centerWheel.transform, M_PI / 500);//累加的角度
}

- (void)stopRotating 停止
{
    [self.link invalidate];
    self.link = nil;
}

62  // 从大图片中裁剪中对应星座的图片
    CGFloat smallW = bigImage.size.width / 12  * [UIScreen mainScreen].scale;
    CGFloat smallH = bigImage.size.height * [UIScreen mainScreen].scale; // CGImageCreateWithImageInRect只认像素
        CGImageRef smallImage = CGImageCreateWithImageInRect(bigImage.CGImage, smallRect); 裁剪图片

63 GCD    dispatch_queue_t 
串行队列,队列中的任务只会顺序执行    dispatch_async   dispatch_sync两个操作都是顺序执行    dispatch_sync主线程上运行 阻塞UI
并行队列,队列中的任务通常会并发执行  dispatch_async操作都是没有顺序的执行    dispatch_sync在主线程顺序的执行阻塞UI

dispatch_queue_t q = dispatch_queue_create("cn.itcast.gcddemo", DISPATCH_QUEUE_SERIAL);

 // 串行行队列的同步任务,同样会在主线程上运行
    // 提示:在开发中极少用d
    // 面试中有可能会问!
    for (int i = 0; i < 10; ++i) {
        // 同步任务顺序执行
        dispatch_sync(q, ^{
            NSLog(@"%@ %d", [NSThread currentThread], i);
        });
    }

for (int i = 0; i < 10; ++i) {
        // 异步任务,并发执行,但是如果在串行队列中,仍然会依次顺序执行
        dispatch_async(q, ^{
            // [NSThread currentThread] 可以在开发中,跟踪当前线程
            // num = 1,表示主线程
            // num = 2,表示第2个子线程。。。
            NSLog(@"%@ %d", [NSThread currentThread], i);
        });
    }

dispatch_queue_t q = dispatch_queue_create("cn.itcast.gcd2", DISPATCH_QUEUE_CONCURRENT);
//    for (int i = 0; i < 10; ++i) {
//        // 异步任务
//        dispatch_async(q, ^{
//            // [NSThread currentThread] 可以在开发中,跟踪当前线程
//            // num = 1,表示主线程
//            // num = 2,表示第2个子线程。。。
//            NSLog(@"%@ %d", [NSThread currentThread], i);
//        });
//    }

for (int i = 0; i < 10; ++i) {
        // 同步任务顺序执行
        dispatch_sync(q, ^{
            NSLog(@"%@ %d", [NSThread currentThread], i);
        });
    }

全局队列(苹果为了方便多线程的设计,提供一个全局队列,供所有的APP共同使用)

dispatch_queue_t q =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_queue_t q =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    for (int i = 0; i < 10; ++i) {
        // 同步任务顺序执行
        dispatch_sync(q, ^{
            NSLog(@"%@ %d", [NSThread currentThread], i);
        });
    }
    
    for (int i = 0; i < 10; ++i) {
        // 异步任务,并发执行,但是如果在穿行队列中,仍然会依次顺序执行
        dispatch_async(q, ^{
            // [NSThread currentThread] 可以在开发中,跟踪当前线程
            // num = 1,表示主线程
            // num = 2,表示第2个子线程。。。
            NSLog(@"%@ %d", [NSThread currentThread], i);
        });
    }

 // 在iOS开发中,所有UI的更新工作,都必须在主线程上执行!
    dispatch_queue_t q = dispatch_get_main_queue();

// 异步任务,在主线程上运行,同时是保持队形的
    for (int i = 0; i < 10; ++i) {
        dispatch_async(q, ^{
            NSLog(@"%@ - %d", [NSThread currentThread], i);
        });
    }

64  NSOperationQueue(操作队列)是由GCD提供的队列模型的Cocoa抽象

self.myQueue = [[NSOperationQueue alloc] init];

NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{
//        NSLog(@"%@", [NSThread currentThread]);
//    }]; 
    // 所有的自定义队列,都是在子线程中运行
//    [self.myQueue addOperation:block];

[self.myQueue setMaxConcurrentOperationCount:2];


    for (int i = 0; i < 10; ++i) {
        [self.myQueue addOperationWithBlock:^{
            NSLog(@"%@ %d", [NSThread currentThread], i);
        }];
    }

#pragma mark 设置任务的执行顺序
- (void)demoOp3
{
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"下载图片 %@", [NSThread currentThread]);
    }];
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"修饰图片 %@", [NSThread currentThread]);
    }];
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"保存图片 %@", [NSThread currentThread]);
    }];
    NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"更新UI %@", [NSThread currentThread]);
    }];
    
    // 设定执行顺序, Dependency依赖,可能会开多个,但不会太多
    // 依赖关系是可以跨队列的!
    [op2 addDependency:op1];
    [op3 addDependency:op2];
    [op4 addDependency:op3];
    // GCD是串行队列,异步任务,只会开一个线程
    
    [self.myQueue addOperation:op1];
    [self.myQueue addOperation:op2];
    [self.myQueue addOperation:op3];
    // 所有UI的更新需要在主线程上进行
    [[NSOperationQueue mainQueue] addOperation:op4];
}

65 如果self对象持有操作对象的引用,同时操作对象当中又直接访问了self时,才会造成循环引用.

单纯在操作对象中使用self不会造成循环引用

class person {- (void)demoOp:(id)obj
{
    NSLog(@"%@ %@", [NSThread currentThread], obj);
}
- (void)demoBlockOp
{
    // 不能用__weak
//    __weak DemoObj *weakSelf = self;
    // 只有self直接强引用block,才会出现循环引用
    // block的管理以及线程的创建和销毁是由队列负责的,直接在block中使用self没有关系!
    for (int i = 0; i < 10; ++i) {
        [self.queue addOperationWithBlock:^{
            [self demoOp:@(i)];
        }];
    }
}}

66 单列  /**
 1. 重写allocWithZone,用dispatch_once实例化一个静态变量
 2. 写一个+sharedXXX方便其他类调用
 */
// 在iOS中,所有对象的内存空间的分配,最终都会调用allocWithZone方法
// 如果要做单例,需要重写此方法
// GCD提供了一个方法,专门用来创建单例的
+ (id)allocWithZone:(struct _NSZone *)zone
{
    static DemoObj *instance;
    
    // dispatch_once是线程安全的,onceToken默认为0
    static dispatch_once_t onceToken;
    // dispatch_once宏可以保证块代码中的指令只被执行一次
    dispatch_once(&onceToken, ^{
        // 在多线程环境下,永远只会被执行一次,instance只会被实例化一次
        instance = [super allocWithZone:zone];
    });
    
    return instance;
}

67 NSThread    [self performSelectorInBackground:@selector(setImagePath:) withObject:@"头像1.png"];

[self performSelectorOnMainThread:@selector(setImage:) withObject:[UIImage imageNamed:imagePath] waitUntilDone:NO];

 1> 不能够自动回收线程,如果并发数量多,会建立大量的子线程!
 2> 使用NSThread的线程,不会自动添加autoreleasepool
  
 
 主线程中是有自动释放池的,使用GCD和NSOperation也会自动添加自动释放池
 
 NSThread和NSObject不会,如果在后台线程中创建了autorelease的对象,需要使用自动释放池,否则会出现内存泄漏!
 
 自动释放池工作原理:
 
 1. 当自动释放池被销毁或者“耗尽”时,对池中的所有对象发送release消息,清空自动释放池
 2. 所有autorelease的对象,在出了作用域之后,会自动添加到【最近一次创建的自动释放池中】自动释放池中
 
 在ARC中,编译器在编译过程中,会自动根据代码结构,添加retain和release。

 

68 SearchBar   UISearchBarDelegate,WebView  UIWebViewDelegate

69 网络get  post

    NSString *urlStr = [NSString stringWithFormat:@"http://localhost/login.php?username=%@&password=%@", self.userName.text, self.userPwd.text]; 
    NSURL *url = [NSURL URLWithString:urlStr]; 
    // 2. Request
    NSURLRequest *request = [NSURLRequest requestWithURL:url];  
    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 
        if (connectionError == nil) {
            // 网络请求结束之后执行!
            // 将Data转换成字符串
            NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            
            // num = 2
            NSLog(@"%@ %@", str, [NSThread currentThread]);
            
            // 更新界面
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                self.logonResult.text = @"登录完成";
            }];
        }
    }];

// 1. URL
    NSURL *url = [NSURL URLWithString:@"http://localhost/login.php"]; 
    // 2. 请求(可以改的请求)
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    // ? POST
    // 默认就是GET请求
    request.HTTPMethod = @"POST";
    // ? 数据体
    NSString *str = [NSString stringWithFormat:@"username=%@&password=%@", self.userName.text, self.userPwd.text];
    // 将字符串转换成数据
    request.HTTPBody = [str dataUsingEncoding:NSUTF8StringEncoding]; 
    // 3. 连接,异步
    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 
        if (connectionError == nil) {
            // 网络请求结束之后执行!
            // 将Data转换成字符串
            NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            
            // num = 2
            NSLog(@"%@ %@", str, [NSThread currentThread]);
            
            // 更新界面
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                self.logonResult.text = str;
            }];
        }
    }];

NSURLConnectionDataDelegate

 // 1. URL
    NSString *urlStr = [NSString stringWithFormat:@"http://localhost/login.php?username=%@&password=%@", self.userName.text, self.myPwd];
    
    NSLog(@"%@", self.myPwd);
    
    NSURL *url = [NSURL URLWithString:urlStr];
    
    // 2. Request
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    // 3. 连接,已经10多岁了
    // 是一个很古老的技术
    NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
    
    // 开始工作,在很多多线程技术中,start run
    dispatch_async(dispatch_queue_create("demo", DISPATCH_QUEUE_CONCURRENT), ^{
        [connection start];
    });

70  JSON的序列化和反序列化

/ 将接收到的二进制数据反序列化为数据字典
            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];

requestM.HTTPBody = [NSJSONSerialization dataWithJSONObject:obj options:0 error:NULL];

71  dispatch_async(dispatch_get_main_queue(), ^{ 
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"网络不给力" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
                
                [alert show];
            }];

  [[NSOperationQueue mainQueue] addOperationWithBlock: ^ {
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"网络不给力" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
                
                [alert show];
            }];

72    可以在storyboard  点击view controller  开启refreshControl 

73 / 
// 在继承子类中,需要使用合成指令生命成员变量
// 在继承自类中,如果需要使用属性的成员变量,需要使用@synthesize指令
@synthesize groups = _groups;

 

74/**
         苹果官方要求,写入文档目录的文件只能是应用本身创建的文件
         从网络上下载的文件,是不能存储在文档目录中的,应该保存在缓存路径中
         */

75  copy  

在堆中的变量,系统只负责维护空间不管变量类型. 
用指针的时候,需要使用类型比如NSString,Person

栈区(1M)  Char Int Float Double

NSCopying   copyWithZone

 深复制:要改地址
 浅复制:不改地址

只有不可变对象创建不可变副本(copy)才是浅复制,其他都是深复制

Int 是在栈区的,效率高,速度快,可以放在方法内部使用
NSNumber是对象,在堆中的,自带了数值转换功能,效率差一些,方便KVC赋值

76  HTTP HEAD方法

request.HTTPMethod = @"HEAD";HEAD方法只是返回资源信息,而不会返回数据体 

获取资源Mimetype
获取资源文件大小,用于端点续传或多线程下载  

77通过设置Range可以指定每次从网路下载数据包的大小

78 多线程下载    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:kTimeOut];

NSFileHandle *fp = [NSFileHandle fileHandleForWritingAtPath:self.cachePath];
// 如果文件不存在,直接写入数据
if (!fp) {
    [data writeToFile:self.cachePath atomically:YES];
} else {
    // 移动到文件末尾
    [fp seekToEndOfFile];
    // 将数据文件追加到文件末尾
    [fp writeData:data];
    // 关闭文件句柄
    [fp closeFile];
}

 

79 UIButton

// 高亮的时候不要自动调整图标
        self.adjustsImageWhenHighlighted = NO; 

// 图标居中
        self.imageView.contentMode = UIViewContentModeCenter;
        // 文字居中
        self.titleLabel.textAlignment = NSTextAlignmentCenter;

 UIButton.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);
    UIButton.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 10);
//    UIButton.contentEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10);

80 NSString *key = @"CFBundleVersion";
      // 获得当前软件的版本号
    NSString *currentVersion = [NSBundle mainBundle].infoDictionary[key];

81 self.tableView.backgroundColor = IWColor(226, 226, 226);
    self.tableView.contentInset = UIEdgeInsetsMake(0, 0, IWStatusTableBorder, 0);

82 

self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

 // 左边按钮
    self.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithIcon:@"navigationbar_friendsearch" highIcon:@"navigationbar_friendsearch_highlighted" target:self action:@selector(findFriend)];
    

83

// 4.通过动画移动按钮(按钮向下移动 btnH + 1)
    [UIView animateWithDuration:0.7 animations:^{
        
        btn.transform = CGAffineTransformMakeTranslation(0, btnH + 2);
        
    } completion:^(BOOL finished) { // 向下移动的动画执行完毕后
        
        // 建议:尽量使用animateWithDuration, 不要使用animateKeyframesWithDuration
        [UIView animateWithDuration:0.7 delay:1.0 options:UIViewAnimationOptionCurveLinear animations:^{
            btn.transform = CGAffineTransformIdentity;
        } completion:^(BOOL finished) {
            // 将btn从内存中移除
            [btn removeFromSuperview];
        }];
        
    }];

84  

    NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
    fmt.dateFormat = @"EEE MMM dd HH:mm:ss Z yyyy";
#warning 真机调试下, 必须加上这段
    fmt.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];

85  [UILabel sizeToFit];  

 // 垂直方向上永远可以拖拽
    textView.alwaysBounceVertical = YES;

86

/**
 让程序保持后台运行
 1.尽量申请后台运行的时间
 [application beginBackgroundTaskWithExpirationHandler:^{
 
 }];
 
 2.在Info.plist中声明自己的应用类型为audio、在后台播放mp3
 */


/**
 *  app进入后台会调用这个方法
 */
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // 在后台开启任务让程序持续保持运行状态(能保持运行的时间是不确定)
    [application beginBackgroundTaskWithExpirationHandler:^{
//        IWLog(@"过期了------");
    }];
    
    // 本地通知,定时提醒(定时弹框)
//    [UILocalNotification ];
}

 

87 

block修改外面的值  加_block  变量,数字变对象@数字      ,-568h@2x修改 Contents.json

88

    self.tableView.sectionHeaderHeight = 5;
    self.tableView.sectionFooterHeight = 0;
    if (iOS7) {
        self.tableView.contentInset = UIEdgeInsetsMake(-30, 0, 0, 0);
    }

89

IWBadgeButton *badgeButton = [[IWBadgeButton alloc] init];
        badgeButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin;

90  UITextFieldDelegate

- (BOO L)textFieldShouldReturn:(UITextField *)textField

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值