1、Xcode必备开发技巧和知识

工作中子控件最好用@property(nonatomic,weak) UIButton *button;   然后self.view addSubview 就实现了强引用了   学习的时候为了快速所以就先用了strong

如果用到懒加载一般用strong

@property(nonatomic,weak) UIActivityIndicatorView *loadingView;
viewDidLoad(){
    [self.view addSubview:loadingView];
    self.loadingView = loadingView;
}

 

-----------------

图文混排 新闻列表用UIWebView 网页来做

-----------------------

多抽方法到分类   自定义控件里   写项目会很快  1-2个星期就一个项目
github.com里有很多好用的分类 有的还有特效

-----------------------

查看api CGRectMake放法的所在位置    则左侧展示出

   

-----------------------

pch文件使用注意  

去公司第一件事情查看公司Log写法 NJLog

(  

  作用

 pch文件的应用常见
 用来定义一些全局的宏 #define Number 10
 用来导入一些全局都能用到的头文件
 用来自定义log

 

// __OBJC__这个宏,在所有的.m和.mm文件中默认就定义了这个宏
#ifdef __OBJC__

// 如果这个全局的头文件或者宏只需要在.m或者.mm文件中使用,
// 请把该头文件或宏写到#ifdef __OBJC__ 中
//  因为  项目中所有文件都会导入这个文件包括.c文件  但是.c文件没有定义__OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
#define ABC 55
#import  "Constant.h"
#ifdef DEBUG 如果程序处于开发阶段 系统会自动定义DEBUG宏 , 如果程序处于发布阶段 系统会删除DEBUG宏定义 #define NJLog(...) NSLog(__VA_ARGS__) ... 代表多个参数 如:NJLog(@"%@-%@-%@-%@",a,b,c,d); NSLog(__VA_ARGS__)为固定写法 NJLog(***)自动转为了NSLog(***)了 #else #define NJLog(...) 去公司第一件事就是看看pch文件 查看Log的替代写法 以后都使用这种方式打印Log 否则会很惨 发布阶段自动删除 NJLog(***) 变成空了 #endif

#define iOS7 ([[UIDevice currentDevice].systemVersion doubleValue] >= 7.0) #endif //#define Number 10 //#import "NJGlobal.h" //如果头文件里用了大量大 #if #endif 应该在这里定义 如NJGlobal.h

 

 

 

-----------------------------

xcode程序常见文件夹和文件

xcode-products文件夹做mac开发用的  iphone开发没有用

Framework下的框架 是开发中所依赖的框架 如fundation框架 xcode-6.4没有这个文件夹了

Test下文件是单元测试用的

InfoPlist.Strings做本地化语言用的

----------------

info.plist文件

info.plist应用程序的配置

修改info.plist 后需要 到模拟器上把应用程序删除  并把xcode product->clean清楚缓存一下

( info.plist也可以在图形化界面里修改 在xcode点击应用程序文件-》genral里设置

bundle display name - 应用程序名称

bundle identifier - 应用程序唯一标识  命名规则倒写域名+应用程序名称

bundle version string,short - 正式的版本号 在itunes上查看到等  app store上传应用程序 后面的版本号数字必须要比大于前一次 否则审核不通过

bundle version - 公司内部人员查看的版本

main storyboard file base name - 首次加载的storyboard名称 如:main

supported interface orientations 屏幕支持的旋转方向

 

------------

ARC项目里有非ARC文件配置

GDataXMLNode.m有release代码  所以是非ARC

xcode->项目-》build phases->设置 GDataXMLNode.m     -fno-objc-arc

------------

程序第一次出错位置  代码出错位置

步骤:

1、添加breakpoint

2、运行程序 ,会停在第一次出错的位置上

3、可以分析出self.index这里出了问题了

 

4、如果程序还是在main中停止了 只有一个原因,就是连线问题

并将

再运行程序 在main中停了 在错误输出中可以找到 出错的连线是哪个了 scrollView

---------------------------------

iphone开发appIcon需要准备的图片

help ->Xcode overview 搜索文章 Icons for iPhone-only Apps

做iphone开发需要准备这些图片就可以了

 

启动图标AppIcon 说明

手机采用点dp作为基本单位 非视网膜屏宽度是320个点

视网膜屏里宽度上占据320个dp点   640px  视网膜屏是320个点 

 

1、

spotlight是搜索出现应用程序的图片

2、

2x   40pt 对应的是80*80像素

 

-------

iphone启动图标 launchImage

R4对应的是retina 4寸屏 iphone5s等 高度为568dp 高度占用1136px

点击查看尺寸, 选择合适素材拖进去

R4找高度568的图片

----------

xcode6.4新建launchImage然后拖动相应图片到对应位置上

设置启动图片配置

(这个是上面内容的来源)http://www.cnblogs.com/w413133157/p/4337516.html (xcode6设置启动图片)

-----------------

下断点看程序执行顺序

---------------

垂直约束 水平约束 取消约束

界面布局设置为 4寸   硬件旋转,如果不正常   然后设置水平约束

----------------

导入其他项目中的素材

找到image.assets->右键 show in finder ->拷贝 别人项目中的image.assets文件夹下的 lol文件夹(里面包含了11233.imageset 1121212.imageset等包装好的图片) 

-》粘贴到自己项目中的image.assets文件夹(lol文件夹存放在image.assets文件夹下)

-----------------

系统头文件修改后处理

xcode->preferences->locations->derived data 进入   删除 derived data换成目录里面的所有文件

----------------

写入代码块

代码块文件位置

xcode->preferences->locations->derived data 同级目录

找到userData/CodeSnippers/代码块文件

我的电脑中代码块位置 /Users/imac/Library/Developer/Xcode/UserData/代码块文件

----------------

 xcode常用快捷键

http://www.cocoachina.com/ios/20141224/10752.html

 -------------

NSArray NSDictionary重写的方法

Log必备文件

- (NSString *)description
{
    return [NSString stringWithFormat:@"<%@: %p> {title: %@, cars: %@}", self.class, self, self.title, self.cars];
}

------

注释小技巧

#if 0

代码

#endif

------

约定

Cell 应该用contentView 不能用backgroundView

-------------

文件夹整理给别人用 Classes - Model Views Controllers  Other目录

根据项目文件夹层次-》show in finder里新建相应的文件夹  把文件拖进去

xcode文件变红色了 -》直接delete -》把show in finder里的文件夹再拖回来

以后新建文件位置都会存放正确了

image.assets storyboard拖到supporting files里   (真实目录里已经是这样 不用管理)

---

代码文件夹管理

storyboard -》image.assets资源文件放到 supporting files里   , 新建MVC group目录  选中文件new group from selected files

 delegate放到others里

mvc + others目录都放到classes目录里 new group from selected files

-------

 自定义对象copy 方法 copyWithZone     0821-tableView cell

Student *p2 =[p copy];

工作中常用的自定义对象copy

//Person.m

- (id)copyWithZone:(NSZone *)zone //zone参数不用管 极少用到 内存用的
{
    // 1> 实例化对象,self 是对象
    // self.class能够保证继承的子类同样使用copy方法
    Person *p = [[self.class alloc] init];
    
    // 2> 给属性赋值
    p.name = self.name;
    p.age = self.age;
    
    // 3> 返回新对象
    return p;
}


//Student.m

- (id)copyWithZone:(NSZone *)zone
{
    // 直接调用父类的copy方法
    Student *s = [super copyWithZone:zone];
    
    // 赋值,只需要给子类的属性赋值即可!
    s.no = self.no;
    
    // 返回
    return s;
}
自定义类 子类和父类copy写法

 

copy简介

 copy简介

 
 
 copy mutableCopy操作导致类型变化:[[array mutableCopy] class]  [[array copy] class] copy === 变成NSArray  mutableCopy == 变成NSMutableArray 具有强制转换效果
 地址变化:[array copy]地址不变 
(对象自定义copyWithZone操作地址会改变 Student *p1 = [p copy];)   [arrayM copy] [arrayM mutableCopy] [array mytableCopy]这3个地址都改变
 
 
 只有执行了 NSMutableArray *arr2 = [arrM copy];  arr2实际上还是NSArray  因为copy转化为NSArray了  左边的NSMutableArray定义是我们一厢情愿罢了  一般也不这么做
 
 @property (nonatomic, copy) NSMutableArray *arr ===  NSMutableArray *arr = [arr copy] 这样 实际上arr是 NSArray了
 
 @property (nonatomic, copy) NSString *name;     
 p.name = strM;//name(NSString类型) 有了copy [strM copy]操作后地址改变了 ,所以 修改strM后不影响 name的值,
 如果name用了strong 就没有copy操作 (p.name和strM地址一样)    这样直接修改strM的内容 也会导致p.name跟着变化  所以不能用strong

 

 

------

strong 和 weak

 strong weak - retain assign - set方法里有release操作 直接赋值基本数据类型不存在release操作  -  强引用 弱引用 - 引用计数器+1 引用计数器不变
__weak Person *p = [[Peson alloc] init];//__weak Person表示 堆区Person对象里引用计数器为0 新创建的Person对象复制给 __weak类型的变量 真实Person对象里的引用计数器为0 过了这一行p会被销毁
所以只有 Person *p = [[Person alloc] init]; __weak Person *p1 = p; p.name=@"aaa"; 这时候p不会销毁了

非arc(非自动代码内存管理)的 set方法

 

#import <Foundation/Foundation.h>

/*
 1.set方法内存管理相关的参数
 * retain : release旧值,retain新值(适用于对象类型)    
 * assign : 直接赋值(默认,适用于非对象类型)
 * copy   : release旧值,copy新值
-(NSArray *)statusFrames
{
    if (_statusFrames == nil) {
        NSString *fullPath = [[NSBundle mainBundle] pathForResource:@"statuses.plist" ofType:nil];
        NSArray *dictArray = [NSArray arrayWithContentsOfFile:fullPath];
        NSMutableArray *models = [NSMutableArray arrayWithCapacity:dictArray.count];
        for (NSDictionary *dict in dictArray) {
            NJWeibo *weibo = [NJWeibo weiboWithDict:dictArray];
            //根据模型数据创建frame模型
            NJWeiboFrame *wbF = [[NJWeiboFrame alloc] init];
            wbF.weibo = weibo;
            [models addObject:wbF];
        }
        self.statusFrames = [models copy];  // copy得到一个新地址  可变数组和不可变数组间通过copy才不报错 否则报错 
    }
    return nil;
}

 

 models copy]转化为了NSArray类型  如果这里不转  会报类型不兼容错误 @property (nonatomic,strong)NSArray *statusFrame;

 

------

block循环引用问题解决
@property (nonatomic,copy) BlockAbc option;
obj.option  =  ^{
    这里面不能出现self   obj   或者强引用obj的对象   如果要使用self 应该用一个若指针变量a指向self 然后在用a来完成操作
}

官方推荐控件使用weak  因为self.view addSubview数组已经强引用sw了

 -

block里可以用self的情况

 这个block可以用self
因为这个block是传递到sendAsynchronousRequest方法里作为一个参数   没有被任何变量强引用

 

-----

NSLog(@"%@",变量)  快捷方式

po 等同于 NSLog(@"%@",noti);

------------

未完成的代码用#warning标记一下

#warning  设置cell高度 未完成的代码      重要的代码位置 以后也方便复习浏览查看

-------

控件不显示原因 打印父控件的frame是否为 0000

如果是父控件frame是 0000  

那么就要在自定义的UITableHeaderFooterView对象里实现方法 - (void)layoutSubviews方法里加载 子控件  而不能在tableview的自定义headerView里修改子空间imageView的frame   CGAffineTrasformTranslate() 里

layoutSubviews在当前控件的frame修改时候会调用

-

自定义Cell 指定storyboard中- tableViewController - TableView - TableViewCell控件的类为自定义Cell

在数据源中创建自定义Cell

自定义cell必须有frame宽度高度  如果没有就会创建一个默认的frame

initWithStyle:style reuseIdentifier:resu//在有storyboard指定cell情况下  ,不要这样写了,因为storyboard已经有一个初始化cell的工作了 ,

如果要进一步对cell进行修改 可以在awakeFromNib里操作(cell子控件里补充初始化的东西 注意这里最好不要设置子控件的frame )  

cell的子控件添加操作只能 [cell.contentView addSubView]

一句话 frame修改 或者子控件frame操作在layoutSubviews(布局子控件)

 

 

控件的设置位置

segue上传下数据(navigationController push),给下控制器的view子控件设置值应该在下控制器的viewDidload()里设置   尤其是在涉及到segue的时候  因为控制器的view是懒加载的

----

@property写法

   // 有的人用strong 也可以 

@property (nonatomic, copy)NSString *str;

@property (nonatomic, weak) id<协议> delegate;

@property (nonatomic, strong)NSMutableArray *messages;

@property (nonatomic, strong)NSArray *arrLists;

@property (nonatomic, assign)CGRect *arrLists;

@property (nonatomic, assign)XXBlock block;

@property (nonatomic, assign)int num;

@property (nonatomic, strong)UILabel *labeltest;//如果用weak 需要先实例化一个对象newLabel并添加到self.view中  再self.labeltest = newLabel;

@property (nonatomic, strong) Class me;

错误的写法@property (nonatomic,strong) UIImageView *newImageView;属性名中不能包含new

#import "HMMessageCell.h"
#import "HMMessageFrameModel.h"
#import "HMMessageModel.h"
#import "Constant.h"
#import "UIImage+ResizImage.h"
@interface HMMessageCell()
//时间
@property (nonatomic, weak)UILabel *time;
//正文
@property (nonatomic, weak)UIButton *textView;
//用户头像
@property (nonatomic, weak)UIImageView *icon;

@end

@implementation HMMessageCell
+ (instancetype)messageCellWithTableView:(UITableView *)tableview
{
    static NSString *ID = @"messageCell";
    HMMessageCell *cell = [tableview dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[self alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
    }
    
    return cell;
}

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
       //1.时间
        UILabel *time = [[UILabel alloc]init];
        time.textAlignment = NSTextAlignmentCenter;
        time.font = [UIFont systemFontOfSize:13.0f];
        [self.contentView addSubview:time];
        self.time = time;
@property (nonatomic, weak)UILabel *time;

 2.@property属性的用法
* weak(assign) :  代理\UI控件
* strong(retain) : 其他对象(除代理\UI控件\字符串以外的对象)
* copy : 字符串
* assign : 非对象类型(基本数据类型int\float\BOOL\枚举\结构体)

----------

block用来存放MBProgressHUD代码

 

属性为block用来保存block方法代码  self.option = 弹出提示框代码(MBProgressHUD)  用的时候直接调用

block快捷键   inlineBlock

block和函数的区别   block本质上和宏差不多    是指向代码的   

运行的时候把某个代码拿来

----------

枚举类型参数上双击然后就可以去掉两边的()

----------

模拟器键盘弹不出处理

模拟器-》硬件-》

一个都不保留  或者只保留 ios uses same layout as osx 

-----------

提示框

MBProgressHUD

我的微云:

 -------------

MJ做的实用框架

https://github.com/CoderMJLee

-----------

左边的xxs.m文件 拖动到 辅助视图右边打开,可以方便些代码   还能看到storyboard  ,很实用

 -----

有的公司可能不允许用storyboard

------

 IOS推出新东西跟进方式

主要方法:ios 7 UI transition guide里面说明了新的api属性用法 【官方文档   最好的】

其他了解即可:

搜索document and api 搜索 ios8 或者 9 或者10.。。

ios6到7有改变的地方 

方法的改变搜索 image imageName方法的改变

----------

stackoverflow 可以找到很多问题答案   专业的it技术问答网站

------

 简单东西说1到2个月完成 万万不可说很短时间 

--------

查看真机沙盒的方法位置

----

真机发送请求任务      不要设置电脑为自己的代理   获取网络数据    否则电脑帮我妈发送了请求了

-------

IOS常用文件

沙盒(程序员创建的应用程序包和 程序员代码实现保存的数据 itunes同步有的数据文件夹会被保存到手机  有的不会同步保存)位置:

【由于不同电脑位置不同 所以这个可以不看 /Users/apple/Library/Application Support/iPhone Simulator/7.0/Applications   (apple是用户名, 7.0是模拟器版本)  代码部署到6.1系统的手机上这里的位置就是6.1】

代码查看应用程序所在在模拟器沙盒文件的位置   /applications/32323ssuuw888应用程序A/  

 

//
//  NJViewController.m
//  05-plist存储数据

#import "NJViewController.h"
#import "NJPerson.h"

@interface NJViewController ()
- (IBAction)saveDataBtnClick:(id)sender;
- (IBAction)readDataBtnClick:(id)sender;

@end

@implementation NJViewController
/**
 *   点击保存按钮
 */
- (IBAction)saveDataBtnClick:(id)sender {
    
    // youtube做法
//    NSString *path = @"/Users/apple/Library/Application Support/iPhone Simulator/7.1/Applications/A6D53E11-DDF0-4392-B2D4-FE77A96888A6/Documents/abc.plist";
    
    // 获取应用程序沙河目录
    NSString *home = NSHomeDirectory();
    // 不建议写/
//    NSString *path = [home stringByAppendingString:@"/Documents"];
    // 不建议Documents写死
//    NSString *path = [home stringByAppendingPathComponent:@"Documents"];
    
    // NSUserDomainMask 在用户目录下查找
    // YES 代表用户目录的~
    // NSDocumentDirectory 查找Documents文件夹
    // 建议使用如下方法动态获取
    NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    // 拼接文件路径
    NSString *path = [doc stringByAppendingPathComponent:@"abc.plist"]
    ;
    NSLog(@"%@", path);
//    NSArray *arr = @[@"lnj", @"28"];
//    [arr writeToFile:path atomically:YES];
    
    // NSDictionary *dict = @{@"name": @"lnj", @"age":@"28"};
    // 调用writeToFile将数据写入文件
    // [dict writeToFile:path atomically:YES];
    
    /*
     plist只能存储系统自带的一些常规的类, 也就是有writeToFile方法的对象才可以使用plist保存数据
     字符串/字典/数据/NSNumber/NSData ...
     */
    
    // 自定义的对象不能保存到plist中
    NJPerson *p = [[NJPerson alloc] init];
    p.name =@"lnj";
    
    NSDictionary *dict = @{@"person": @"abc"};
    [dict writeToFile:path atomically:YES]; //文件写入都这么使用 线程安全 先往临时文件里写,再变成真实的文件  防止程序中断
}
/**
 *   点击读取按钮
 */
- (IBAction)readDataBtnClick:(id)sender {
    NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    
    NSString *path = [doc stringByAppendingPathComponent:@"abc.plist"]
    ;
    // 读取数据
    NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
    NSLog(@"%@", dict);
}
@end
查看沙盒位置 存储数据到沙盒里

 

ios8开放了不同应用程序互相访问其沙盒

 

文件在itunes上同步(备份操作iphone ipad应用和内容的作用)的时候会被保存在itunes上

layer是应用程序压缩包 不能存东西

【 记住一点即可  数据放到Documents里就好了   但是Document目录不能放太大文件    因为会同步到itunes   苹果会对app进行测试发现很大文件网Document里面写可能会被拒绝审核通过的

Documents

Library

  Caches 很多不重要的大文件存放位置 不会被同步

  Preferences  【很小的用户偏好plist可以存放一下

一般我们这个不用管,系统自动放数据     系统的偏好设置iphone-setting信息会保存在这里  我们一般不保存数据在这里    ,用户的偏好数据  如打开应用程序sogou 有一个偏好设置字体颜色   下次同步数据后这个会保存  】  

tmp 应用程序结束 应该清理 系统也可能会自动清理 不会被itunes同步保存

数据存储

xml - plist       存储常用数据类型

preference(偏好设置) 本质也是plist

NSKeyedArchiver归档(NSCoding)  自定义对象的存储

SQLite3

Core Data  (数据库缺点不能存储对象 那么Core Data可以存储对像  实际上本质也是SQLite)
数据存储的其他方式

 -

NSUserdefaults 自动保存数据到 preference文件夹下   但是只能保存一个plist(一个Array 下的n个dictionary的数据)

所以一般数据不在这里保存

NSUserdefaults对象自动保存数据到Preference目录下的***.plist里

preferences的应用场景如下: 登录过后 保存第一次登录选择和写入的数据

-------

 

 

 

 

-----

显示隐藏文件  桌面操作这里不介绍了

显示:defaults write com.apple.finder AppleShowAllFiles -bool true
隐藏:defaults write com.apple.finder AppleShowAllFiles -bool false

finder->强制退出-》重启finder

-----

View和控制器的创建

初始化创建的时候采用  获取xib和不获取xib的方式

控制器有自动初始化view的操作

------

单例获取常用关键字: main shared current standard default  拿到单例的方法

-------

辅助编辑模式用上下模式

xcode->view -> assistant editor -> assistant editors  on bottom

-------

设计原则

方法里创建的控制器 过了这个方法就会被销毁

需要添加这个view的时候 也添加这个控制器

 

   一个视图添加子视图 jump.view 的时候  需要同时添加jump  ,   防止调到jump控制器过了这个btnClick方法被销毁

 

-------

QQ主流框架手动拖一拖

----------

viewDidApper里打印view的内容更准确

-----------

快速修改类名称

.h文件右键-》refactor->rename

 --------

navigationController上面也可以隐藏掉 

控制器关系紧密用UINavigationController 不紧密用Modal

----------

在方法名、类名上   上按住 option -》点击?-》弹出api文档简要解释    或者光标放在方法上 右侧也能看到api解释

如果想跳到苹果api文档里 可以在最下面的class reference 点击一下   就可以弹出其api文档了

API文档里还有sample code

------

看开发文档学习各种框架使用

 ---------

autoResizing

 

posted @ 2016-02-24 14:56  海龙王来了  阅读(319)  评论(0)    收藏  举报
友情链接:废钢破碎机  带式压滤机