Introduction to common project documents
I. Schematic diagram of project document structure
Ii. Introduction of documents
1.products folder: An executable file used primarily for Mac development, which is not available for iOS development
2.frameworks folders are primarily used to put dependencies on the framework
3.test folders are used for unit testing.
4. Commonly used folders (Project name folder)
(1) xxxinfo.plist file (01 in this project-common file-info.plist)
1) Simple description
Is the configuration file, the file on the project to do some run-time configuration, very important, can not be deleted.
In a project created by an older version of Xcode, the name of this configuration file is called Info.plist.
Note: Therefore, do not name info when loading the plist file you have prepared.
2 Description of the properties of the configuration file:
Bundle Display Name:
The application display name. If you want to modify the name of the file displayed on your desktop, just modify it here. (You need to remove the original program, and then clear the project, because the program has a cache)
Bundle Identifer:
Unique identifier (uniquely identifies an application that, in order to guarantee the uniqueness of the program, usually writes the domain name backwards)
Bundle versions string, short and Bundle versions
Two are used to represent the version of the application, the previous version is a formal version, followed by the internal version, that is, the internal development of the company version. Request hint: When uploading the app, the later version must be larger than the previous version.
Main Storyboard File base name
The main storyboard
There are two ways to modify the plist configuration file:
The first way is to modify the configuration information as shown in the diagram.
The second way to directly click the project, can be set through the visual interface.
Supplementary Note:
A. The direction of rotation supported by the application. Four directions, vertical-not supported upside down-left-right (up to three directions only)
After the B.plist file is opened, it is an XML file. As with dictionaries, data is stored in the form of key-value pairs. In the XML file, the CF prefix was added
(2) PCH file (01-common file-prefix.pch in this project)
1) Simple description
The saved content can be shared by all other original files in the project.
In general, the macro file processing, you need to add import imports header file. You can later define this macro in this file and no longer need to import header files
2) Application Scenario:
1. To define some global macros,
2. Used to import some of the global can use the header files.
3. The use of nslog from the definition is very resource consuming. (almost the most consumed), to remove all printing when it is released.
(Supplement: In development, it is divided into two stages.)
First, the development of debugging phase, the need to print log debugger, if the program is in the debugging phase, the system will define a name for us, called Debug macros.
The second is the release phase: Do not need to print log, because log is very resource-intensive, and users can not read log, if the program to process the release phase, will remove the macro.
Would you like to comment out the nslog at the time of release? And then when you develop the second and third editions, do you want to open all the annotated nslog?
For this problem, customizing the NSLog in the. pch file can be a good solution. )
3) Custom NSLog
In the development of the time you can open the PCH file, to see if the company has a custom nslog.
Copy Code code as follows:
__OBJC__ This macro, this macro is defined by default in all. m and. mm files.
#ifdef __objc__
If this global header file or macro only needs to be used in the. m or. mm file,
Please write the header file or macro to #ifdef __objc__.
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#ifdef DEBUG
#define NJLOG (...) NSLog (__va_args__)
#else
#define NJLOG (...)
#endif
#endif
Description: ... refers to receiving variable parameters
Add:
_OBJC_ This macro, which is included in all. m and. mm files by default, will compile the following two sentences
Conditional compilation statement, if you have this macro, compile the following statement.
Copy Code code as follows:
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
If this global header file or macro only needs to be used in the. m or. mm file, write the file or macro to #ifdef_odbc_.
Note: Suggest writing in conditional compilation (note #endif)
infoplist.strings files, related to localization of info.plist files
Looking at MVC from the step-by-Step optimization of code
I. Requirements
Required to complete a small application below.
Two or one steps to optimize your code
Note: During the development process, the process of optimization is done step-by-step. (If a person to eat five buns to eat full, then he ate the fifth directly, the first four do not have to eat on the full?) )
1. Code to complete the basic requirements (using the dictionary-turn model and xib wiring)
(1) File structure
(2) Main code
Part of the dictionary-turn model:
YYappInfo.h header File
Copy Code code as follows:
//
YYappInfo.h
12-View Improvements (1)
//
Created by Apple on 14-5-25.
Copyright (c) 2014 itcase. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Yyappinfo:nsobject
@property (nonatomic,copy) NSString *name;
@property (nonatomic,copy) NSString *icon;
@property (nonatomic,strong,readonly) uiimage *img;
-(Instancetype) Initwithdict: (Nsdictionary *) dict;
/** Factory Method * *
+ (Instancetype) appinfowithdict: (Nsdictionary *) dict;
@end
YYAPPINFO.M file
Copy Code code as follows:
//
// YYAPPINFO.M
// 12-View improvements (1)
//
//&NBSP ; Created by Apple on 14-5-25.
// Copyright (c) 2014 itcase. All rights reserved.
//
#import "YYappInfo.h"
@interface yyappinfo ()
{
uiimage *_img;
}
@end
@implementation yyappinfo
-(Instancetype) Initwithdict: (nsdictionary *) dict
{
if (self=[super init]) {
self.name=dict[@ ' name '];
self.icon=dict[@ "icon"];
}
return self;
}
+ (Instancetype) appinfowithdict: (nsdictionary *) dict
{
return [[Self alloc] INITWITHDICT:DICT];
}
-(uiimage *) img
{
_img=[uiimage ImageNamed:self.icon];
return _img;
}
@end
Xib section (YYappInfoView.h file):
Note: (xib view is associated with Yyappinfoview, three properties are wired)
Copy Code code as follows:
//
YYappInfoView.h
12-View Improvements (1)
//
Created by Apple on 14-5-25.
Copyright (c) 2014 itcase. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface Yyappinfoview:uiview
@property (Strong, nonatomic) Iboutlet Uiimageview *appinfoviewimg;
@property (Strong, nonatomic) Iboutlet Uilabel *appinfoviewlab;
@property (Strong, nonatomic) Iboutlet UIButton *appinfoviewbtn;
@end
Main function Realization part:
YYVIEWCONTROLLER.M file
Copy Code code as follows:
//
Yyviewcontroller.m
12-View Improvements (1)
//
Created by Apple on 14-5-25.
Copyright (c) 2014 itcase. All rights reserved.
//
#import "YYViewController.h"
#import "YYappInfo.h"
#import "YYappInfoView.h"
@interface Yyviewcontroller ()
@property (Nonatomic,strong) Nsarray *apps;
@end
Copy Code code as follows:
Development ideas
1. Loading plist file (dictionary model provides interface)
2. Use Xib file to complete a single view
3. Compute the coordinates and use the For loop to show the view to the interface
4. Optimize the Code
@implementation Yyviewcontroller
Get method, lazy load
-(Nsarray *) apps
{
if (!_apps) {
NSString *path = [[NSBundle mainbundle]pathforresource:@ "App.plist" oftype:nil];
Nsarray * Arraym = [Nsarray Arraywithcontentsoffile:path];
Nsmutablearray *appinfoarray=[nsmutablearray Array];
For (Nsdictionary *dict in Arraym) {
[Appinfoarray Addobject:[yyappinfo Appinfowithdict:dict]];
}
_apps = Appinfoarray;
}
return _apps;
}
-(void) viewdidload
{
[Super Viewdidload];
NSLog (@ "%d", self.apps.count);
int totalloc = 3;
CGFloat appvieww = 80;
CGFloat APPVIEWH = 90;
CGFloat margin = (self.view.frame.size.width-totalloc*appvieww)/(totalloc+1);
int count=self.apps.count;
for (int i = 0; i < count; i++) {
int row = I/totalloc;
int loc = I%totalloc;
CGFloat appviewx = margin + (margin + appvieww) * LOC;
CGFloat appviewy = margin + (margin + appviewh) * ROW;
Yyappinfo *appinfo=self.apps[i];
Take out the data in the Xib
Nsarray *arrym=[[nsbundle mainbundle]loadnibnamed:@ "Appinfoxib" Owner:nil Options:nil];
Yyappinfoview *appinfoview=[arrym Firstobject];
Set Location
Appinfoview.frame=cgrectmake (Appviewx, Appviewy, APPVIEWW, APPVIEWH);
Setting values
appinfoview.appinfoviewimg.image=appinfo.img;
Appinfoview.appinfoviewlab.text=appinfo.name;
Add to view
Appinfoview.appinfoviewbtn.tag=i;
[Appinfoview.appinfoviewbtn addtarget:self Action: @selector (Click:) forcontrolevents:uicontroleventtouchupinside] ;
[Self.view Addsubview:appinfoview];
}
}
-(void) Click: (UIButton *) btn
{
Btn.enabled=no;
Yyappinfo *appinfo=self.apps[btn.tag];
Uilabel *lab=[[uilabel Alloc]initwithframe:cgrectmake (60, 450, 200, 20)];
[Lab Setbackgroundcolor:[uicolor Lightgraycolor]];
[Lab Settextalignment:nstextalignmentcenter];
[Lab settext:[nsstring stringwithformat:@ "%@ successfully downloaded", Appinfo.name]];
[Self.view Addsubview:lab];
lab.alpha=1.0;
[UIView animatewithduration:2.0 animations:^{
lab.alpha=0;
}completion:^ (BOOL finished) {
[Lab Removefromsuperview];
}];
}
@end
2. Optimize for 1 (encapsulate the data rendering part into view)
Description: On the basis of 1 to find there will be those who can optimize the part
1) Improve the idea:
(1) 1 can the 66~67 row of the main file have the control properties set to the view?
(2) The 61~62 line in 1 is an operation that reads information from a xib file, and is not too much associated with the host controller, can it also be encapsulated into a view?
(3) When the above two steps are completed, the main file 69 lines after the button operation and button click event is very abrupt, placed in the main controller is no longer appropriate, whether it can be placed in the view of processing
2 According to the above ideas optimized after the code is as follows:
Optimizes the view, provides an interface to the external part of the view, and encapsulates the processing of the data internally
YYappInfoView.h File Code:
Copy Code code as follows:
//
YYappInfoView.h
12-View Improvements (1)
//
Created by Apple on 14-5-25.
Copyright (c) 2014 itcase. All rights reserved.
//
#import <UIKit/UIKit.h>
@class Yyappinfo;
@interface Yyappinfoview:uiview
Read
+ (instancetype) Appinfoview;
Open only one data interface
+ (Instancetype) Appinfoviewwithappinfo: (Yyappinfo *) appinfo;
@end
YYAPPINFOVIEW.M File Code
Description: The properties of the file and click, etc. have done the operation of the connection.
Copy Code code as follows:
//
yyappinfoview.m
12-View Improvements (1)
//
Created by Apple on 14-5-25.
Copyright (c) 2014 itcase. All rights reserved.
//
#import "YYappInfoView.h"
#import "YYappInfo.h"
Private extension, bring the attribute in
@interface Yyappinfoview ()
@property (Strong, nonatomic) Iboutlet Uiimageview *appinfoviewimg;
@property (Strong, nonatomic) Iboutlet Uilabel *appinfoviewlab;
@property (Strong, nonatomic) Iboutlet UIButton *appinfoviewbtn;
@property (strong,nonatomic) Yyappinfo *appinfo;
@end
Copy Code code as follows:
@implementation Yyappinfoview
+ (Instancetype) Appinfoview
{
Nsarray *arrym=[[nsbundle mainbundle]loadnibnamed:@ "Appinfoxib" Owner:nil Options:nil];
Yyappinfoview *appinfoview=[arrym Firstobject];
return appinfoview;
}
+ (Instancetype) Appinfoviewwithappinfo: (Yyappinfo *) appinfo
{
Yyappinfoview *appinfoview=[self Appinfoview];
Appinfoview.appinfo=appinfo;
return appinfoview;
}
-(void) Setappinfo: (Yyappinfo *) APPINFOC
{
There must be a record of change.
_APPINFO=APPINFOC;
self.appinfoviewimg.image=appinfoc.img;
Self.appinfoviewlab.text=appinfoc.name;
}
-(ibaction) Click {
Self.appinfoviewbtn.enabled=no;
Yyappinfo *appinfo=self.apps[];
Yyappinfo *appinfo=self.appinfo;
Uilabel *lab=[[uilabel Alloc]initwithframe:cgrectmake (60, 450, 200, 20)];
[Lab Setbackgroundcolor:[uicolor Lightgraycolor]];
[Lab Settextalignment:nstextalignmentcenter];
[Lab settext:[nsstring stringwithformat:@ "%@ successfully downloaded", Appinfo.name]];
Add Lab to Parent view (that is, view)
[Self.superview Addsubview:lab];
lab.alpha=1.0;
[UIView animatewithduration:2.0 animations:^{
lab.alpha=0;
}completion:^ (BOOL finished) {
[Lab Removefromsuperview];
}];
}
@end
The optimized main controller section
YYVIEWCONTROLLER.M File Code
Copy Code code as follows:
//
Yyviewcontroller.m
12-View Improvements (1)
//
Created by Apple on 14-5-25.
Copyright (c) 2014 itcase. All rights reserved.
//
#import "YYViewController.h"
#import "YYappInfo.h"
#import "YYappInfoView.h"
@interface Yyviewcontroller ()
@property (Nonatomic,strong) Nsarray *apps;
@end
Copy Code code as follows:
@implementation Yyviewcontroller
-(Nsarray *) apps
{
if (!_apps) {
NSString *path = [[NSBundle mainbundle]pathforresource:@ "App.plist" oftype:nil];
Nsarray * Arraym = [Nsarray Arraywithcontentsoffile:path];
Nsmutablearray *appinfoarray=[nsmutablearray Array];
For (Nsdictionary *dict in Arraym) {
[Appinfoarray Addobject:[yyappinfo Appinfowithdict:dict]];
}
_apps = Appinfoarray;
}
return _apps;
}
-(void) viewdidload
{
[Super Viewdidload];
NSLog (@ "%d", self.apps.count);
int totalloc = 3;
CGFloat appvieww = 80;
CGFloat APPVIEWH = 90;
CGFloat margin = (self.view.frame.size.width-totalloc*appvieww)/(totalloc+1);
int count=self.apps.count;
for (int i = 0; i < count; i++) {
int row = I/totalloc;
int loc = I%totalloc;
CGFloat appviewx = margin + (margin + appvieww) * LOC;
CGFloat appviewy = margin + (margin + appviewh) * ROW;
/* Thinking:
To achieve the effect of appinfoview.appinfo=appinfo;
After optimization, it becomes appinfoview.appinfo=self.apps[i];
To do the above code, you need to add a new AppInfo class attribute in the view so that the data-view conversion can be done without having to be completed in the main controller, so that the program structure is self-explanatory.
*/
Yyappinfo *appinfo=self.apps[i];
Yyappinfoview *appinfoview=[yyappinfoview Appinfoviewwithappinfo:appinfo];
Set Location
Appinfoview.frame=cgrectmake (Appviewx, Appviewy, APPVIEWW, APPVIEWH);
Add to
[Self.view Addsubview:appinfoview];
}
}
@end
3. Further optimization for 2 (take the data processing part to the model)
(1) Thinking: The Dictionary to the model part of the data processing operations, get the model to deal with, so that the outside world does not need to care about the internal details of data processing.
(2) After the optimized code is as follows
Open an interface to the YYappInfo.h file to return a processed array.
Copy Code code as follows:
//
YYappInfo.h
12-View Improvements (1)
//
Created by Apple on 14-5-25.
Copyright (c) 2014 itcase. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Yyappinfo:nsobject
@property (nonatomic,copy) NSString *name;
@property (nonatomic,copy) NSString *icon;
@property (Nonatomic,strong) uiimage *img;
-(Instancetype) Initwithdict: (Nsdictionary *) dict;
/** Factory Method * *
+ (Instancetype) appinfowithdict: (Nsdictionary *) dict;
+ (Nsarray *) Appinfoarray;
@end
Data processing in the YYAPPINFO.M file
//
Yyappinfo.m
12-View Improvements (1)
//
Created by Apple on 14-5-25.
Copyright (c) 2014 itcase. All rights reserved.
//
#import "YYappInfo.h"
@interface Yyappinfo ()
@end
Copy Code code as follows:
@implementation Yyappinfo
-(Instancetype) Initwithdict: (Nsdictionary *) dict
{
if (Self=[super init]) {
self.name=dict[@ "Name"];
self.icon=dict[@ "icon"];
}
return self;
}
+ (Instancetype) appinfowithdict: (Nsdictionary *) dict
{
return [[Self alloc]initwithdict:dict];
}
-(UIImage *) img
{
_img=[uiimage ImageNamed:self.icon];
return _img;
}
Take the data processing part to the model to deal with
+ (Nsarray *) Appinfoarray
{
NSString *path = [[NSBundle mainbundle]pathforresource:@ "App.plist" oftype:nil];
Nsarray * Arraym = [Nsarray Arraywithcontentsoffile:path];
Nsmutablearray *appinfoarray=[nsmutablearray Array];
For (Nsdictionary *dict in Arraym) {
[Appinfoarray Addobject:[yyappinfo Appinfowithdict:dict]];
}
return appinfoarray;
}
@end
No more attention to the internal details of data processing in the main controller
The yyviewcontroller.m file is now only responsible for the coordination between the model and the view, how about? It's almost done.
Copy Code code as follows:
//
Yyviewcontroller.m
12-View Improvements (1)
//
Created by Apple on 14-5-25.
Copyright (c) 2014 itcase. All rights reserved.
//
#import "YYViewController.h"
#import "YYappInfo.h"
#import "YYappInfoView.h"
@interface Yyviewcontroller ()
@property (Nonatomic,strong) Nsarray *apps;
@end
Copy Code code as follows:
@implementation Yyviewcontroller
-(Nsarray *) apps
{
if (!_apps) {
_apps=[yyappinfo Appinfoarray];
}
return _apps;
}
-(void) viewdidload
{
[Super Viewdidload];
int totalloc = 3;
CGFloat appvieww = 80;
CGFloat APPVIEWH = 90;
CGFloat margin = (self.view.frame.size.width-totalloc*appvieww)/(totalloc+1);
int count=self.apps.count;
for (int i = 0; i < count; i++) {
int row = I/totalloc;
int loc = I%totalloc;
CGFloat appviewx = margin + (margin + appvieww) * LOC;
CGFloat appviewy = margin + (margin + appviewh) * ROW;
Yyappinfo *appinfo=self.apps[i];
Yyappinfoview *appinfoview=[yyappinfoview Appinfoviewwithappinfo:appinfo];
Appinfoview.frame=cgrectmake (Appviewx, Appviewy, APPVIEWW, APPVIEWH);
[Self.view Addsubview:appinfoview];
}
}
@end
Implementation effect:
4. Supplementary notes
The package idea of view
(1) If you have more child controls inside a view, you will typically consider customizing a view to shield the creation of its inner child controls from outside care
(2) The external can pass the corresponding model data to the View,view to get the model data to set the corresponding data to the internal child control
Three, the MVC mechanism simple explanation
Description
(1) In the development process, as a controller to deal with the magnitude should be very light, should not worry about not worry. It's OK to coordinate models and views and learn to be a good boss.
(2) Three parts of their respective roles, the data model is responsible for data processing, the view is only responsible for the data to be displayed, two parts are passive, waiting for the large butler controller.
(3) in OC, if there is a channel between the view and the data model, is the controller in a state of control?