最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Objective-C中編程中一些推薦的書寫規(guī)范小結(jié)

 更新時間:2016年04月07日 09:17:57   作者:ForeverYoung21  
這篇文章主要介紹了Objective-C的一些編程書寫規(guī)范小結(jié),包括類與方法等面向?qū)ο缶幊滔嚓P(guān)的代碼編寫風(fēng)格,需要的朋友可以參考下

一、類
1. 類名
類名應(yīng)該以三個大寫字母作為前綴(雙字母前綴為Apple的類預(yù)留)

不僅僅是類,公開的常量、Protocol等的前綴都為相同的三個大寫字母。

當(dāng)你創(chuàng)建一個子類的時候,你應(yīng)該把說明性的部分放在前綴和父類名的中間。

例如:

如果你有一個 ZOCNetworkClient 類,子類的名字會是ZOCTwitterNetworkClient (注意 "Twitter" 在 "ZOC" 和 "NetworkClient" 之間); 按照這個約定, 一個UIViewController 的子類會是 ZOCTimelineViewController.

2. Initializer和dealloc
推薦的代碼組織方式是將dealloc方法放在實現(xiàn)文件的最前面(直接在@synthesize以及@dynamic之后),init應(yīng)該跟在dealloc方法后面。

如果有多個初始化方法,那么指定初始化方法應(yīng)該放在最前面,間接初始化方法跟在后面。

如今有了ARC,dealloc方法幾乎不需要實現(xiàn),不過把init和dealloc放在一起,強(qiáng)調(diào)它們是一對的。通常在init方法中做的事情需要在dealloc方法中撤銷。

關(guān)于指定初始化方法(designated initializer)和間接初始化方法(secondary initializer)

Objective-C 有指定初始化方法(designated initializer)和間接(secondary initializer)初始化方法的觀念。 designated 初始化方法是提供所有的參數(shù),secondary 初始化方法是一個或多個,并且提供一個或者更多的默認(rèn)參數(shù)來調(diào)用 designated 初始化的初始化方法。

復(fù)制代碼 代碼如下:

@implementation ZOCEvent

- (instancetype)initWithTitle:(NSString *)title
                         date:(NSDate *)date
                     location:(CLLocation *)location
{
    self = [super init];
    if (self) {
        _title    = title;
        _date     = date;
        _location = location;
    }
    return self;
}

- (instancetype)initWithTitle:(NSString *)title
                         date:(NSDate *)date
{
    return [self initWithTitle:title date:date location:nil];
}

- (instancetype)initWithTitle:(NSString *)title
{
    return [self initWithTitle:title date:[NSDate date] location:nil];
}

@end


initWithTitle:date:location: 就是 designated 初始化方法,另外的兩個是 secondary 初始化方法。因為它們僅僅是調(diào)用類實現(xiàn)的 designated 初始化方法。

一個類應(yīng)該有且只有一個 designated 初始化方法,其他的初始化方法應(yīng)該調(diào)用這個 designated 的初始化方法(有例外)。

3. 當(dāng)定義一個新類的時候有三個不同的方式:
(1)不需要重載任何初始化函數(shù)
(2)重載 designated initializer
(3)定義一個新的 designated initializer
第一種方式不需要增加類的任何初始化邏輯,也就是說在類中不必重寫父類的初始化方法也不需要其他操作。

第二種方式要重載父類的指定初始化方法。例子:

復(fù)制代碼 代碼如下:

@implementation ZOCViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    // call to the superclass designated initializer
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization (自定義的初始化過程)
    }
    return self;
}

@end


這個例子中,ZOCViewController繼承自UIViewController,這里我們有一些其他的需求(比如希望在初始化的時候給一些成員變量賦值),所以需要重寫父類的指定初始化方法initWithNibName:bundle:方法。

注意,如果在這里并沒有重載這個方法,而是重載了父類的init方法,那么會是一個錯誤。

因為在創(chuàng)建這個類(ZOCViewController)的時候,會調(diào)用initWithNib:bundle:這個方法,所以我們重載這個方法,首先保證父類初始化成功,然后在這個方法中進(jìn)行額外的初始化操作。但是如果重載init方法,在創(chuàng)建這個類的時候,并不會調(diào)用init方法(調(diào)用的是initWithNib:bundle:這個指定初始化方法)。

第三種方式是希望提供自己的類初始化方法,應(yīng)該遵守下面三個步驟來保證正確性:

定義你的 designated initializer,確保調(diào)用了直接超類的 designated initializer。
重載直接超類的 designated initializer。調(diào)用你的新的 designated initializer。
為新的 designated initializer 寫文檔。
很多開發(fā)者會忽略后兩步,這不僅僅是一個粗心的問題,而且這樣違反了框架的規(guī)則,而且可能導(dǎo)致不確定的行為和bug。

正確的例子:

復(fù)制代碼 代碼如下:

@implementation ZOCNewsViewController

- (id)initWithNews:(ZOCNews *)news
{
    // call to the immediate superclass's designated initializer (調(diào)用直接超類的 designated initializer)
    self = [super initWithNibName:nil bundle:nil];
    if (self) {
        _news = news;
    }
    return self;
}

// Override the immediate superclass's designated initializer (重載直接父類的  designated initializer)
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    // call the new designated initializer
    return [self initWithNews:nil];
}

@end


​很多開發(fā)者只會寫第一個自定義的初始化方法,而不重載父類的指定初始化方法。

在第一個自定義的初始化方法中,因為我們要定義自己的指定初始化方法,所以在最開始的時候首先要調(diào)用父類的指定初始化方法以保證父類都初始化成功,這樣ZOCNewsViewController才是可用狀態(tài)。(因為父類是通過initWithNibName:bundle:這個指定初始化方法創(chuàng)建的,所以我們要調(diào)用父類的這個方法來保證父類初始化成功)。然后在后面給_news賦值。

​如果僅僅是這樣做是存在問題的。調(diào)用者如果調(diào)用initWithNibName:bundle:來初始化這個類也是完全合法的,如果是這種情況,那么initWithNews:這個方法永遠(yuǎn)不會被調(diào)用,所以_news = news也不會被執(zhí)行,這樣導(dǎo)致了不正確的初始化流程。

解決方法就是需要重載父類的指定初始化方法,在這個方法中返回新的指定初始化方法(如例子中做的那樣),這樣無論是調(diào)用哪個方法都可以成功初始化。

間接初始化方法是一種提供默認(rèn)值、行為到初始化方法的方法。

你不應(yīng)該在間接初始化方法中有初始化實例變量的操作,并且你應(yīng)該一直假設(shè)這個方法不會得到調(diào)用。我們保證的是唯一被調(diào)用的方法是 designated initializer。

這意味著你的 secondary initializer 總是應(yīng)該調(diào)用 Designated initializer 或者你自定義(上面的第三種情況:自定義Designated initializer)的 self的 designated initializer。有時候,因為錯誤,可能打成了 super,這樣會導(dǎo)致不符合上面提及的初始化順序。

也就是說,你可能看到一個類有多個初始化方法,實際上是一個指定初始化方法(或多個,比如UITableViewController就有好幾個)+多個間接初始化方法。這些簡潔初始化方法可能會根據(jù)不同的參數(shù)做不同的操作,但是本質(zhì)上都是調(diào)用指定初始化方法。所以說,間接初始化方法是有可能沒有調(diào)用到的,但是指定初始化方法是會調(diào)用到的(并不是每一個都會調(diào)用到,但是最后調(diào)用的一定是一個指定初始化方法)。(這里又可以引申到上面提到的問題,我們可以直接重寫父類的指定初始化方法,也可以自定義初始化方法(在這個方法中需要用到self = [super 父類初始化方法]這種形式的代碼),并且如果是自定義初始化方法,還應(yīng)該重寫從父類繼承的初始化方法來返回我們的自定義初始化方法…)。

總之就是,如果重寫父類的指定初始化方法首先需要調(diào)用父類的相應(yīng)初始化方法;如果增加自定義指定初始化方法,首先在新增的自定義指定初始化方法中調(diào)用父類的相應(yīng)初始化方法,然后需要重寫父類的指定初始化方法,在重寫的方法中調(diào)用剛剛添加的自定義指定初始化方法。

4.補(bǔ)充

一個類可能有多個指定初始化方法,也有可能只有一個指定初始化方法。

以UITableViewController為例,我們可以看到:

復(fù)制代碼 代碼如下:

- (instancetype)initWithStyle:(UITableViewStyle)style NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;

它有三個指定初始化方法,我們剛才說,當(dāng)子類從父類繼承并重寫初始化方法,首先需要調(diào)用父類的初始化方法,但是如果一個類的初始化方法有多個,那么需要調(diào)用哪個呢?

事實上不同的創(chuàng)建方式要調(diào)用不同的指定初始化方法。

比如,我們以Nib的形式創(chuàng)建UITableViewController,那么最后調(diào)用的就是- (instancetype)initWithNibName:(NSString )nibNameOrNil bundle:(NSBundle )nibBundleOrNil這個指定初始化方法;如果我們以Storyboard的形式創(chuàng)建,那么最后調(diào)用的就是- (instancetype)initWithCoder:(NSCoder *)aDecoder這個指定初始化方法。如果以代碼的形式創(chuàng)建,那么最后調(diào)用的就是- (instancetype)initWithStyle:(UITableViewStyle)style這個指定初始化方法。所以不同的情況需要重寫不同的指定初始化方法,并且重寫的時候首先要調(diào)用父類相應(yīng)的指定初始化方法(比如重寫initWithCoder:方法,那么首先self = [super initWithCoder:…],都是一一對應(yīng)的)。

再以UIViewController為例,我們以Nib的形式創(chuàng)建UIViewController,那么最后調(diào)用的是- (instancetype)initWithNibName:(NSString )nibNameOrNil bundle:(NSBundle )nibBundleOrNil,這與UITableViewController是一樣的;如果我們以Storyboard的形式創(chuàng)建,那么最后調(diào)用的是- (instancetype)initWithCoder:(NSCoder )aDecoder,這與UITableViewController也是一樣的;但是如果我們以代碼的形式創(chuàng)建UIViewController(eg: CYLViewController vc = [[CYLViewController alloc] init]; CYLViewController繼承自UIViewController),那么它最后調(diào)用的實際是- (instancetype)initWithNibName:(NSString )nibNameOrNil bundle:(NSBundle )nibBundleOrNil,這與UITableViewController是不一樣的,因為UIViewController并沒有- (instancetype)initWithStyle:(UITableViewStyle)style這個方法,所以當(dāng)用代碼創(chuàng)建的時候,最后調(diào)用的也是initWithNibName:bundle這個指定初始化方法,并且參數(shù)自動設(shè)置為nil。

所以現(xiàn)在反過頭來再看UITableViewController,當(dāng)使用代碼的方式創(chuàng)建的時候(eg: CYLTableViewController tvc = [[CYLTableViewController alloc] init]; 或者 CYLTableViewController tvc = [[CYLTableViewController alloc] initWithStyle: UITableViewStylePlain]; ),它會調(diào)用initWithStyle:這個方法,但是如果你也實現(xiàn)了initWithNibName:bundle:這個方法,你會發(fā)現(xiàn)這個方法也被調(diào)用了。因為UITableViewController繼承自UIViewController,所以當(dāng)用代碼創(chuàng)建的時候,最后也會掉用到initWithNIbName:bundle:(因為UIViewController就是這么干的)。

所以用代碼創(chuàng)建UITableViewController的時候,它會調(diào)用initWithNibName:bundle:和initWithStyle:這兩個方法。

二、屬性
屬性要盡可能描述性地命名,并且使用駝峰命名。

關(guān)于”*”的位置:

復(fù)制代碼 代碼如下:

// 推薦
NSString *text;

// 不推薦
NSString* text;
NSString * text;


注意,這個習(xí)慣和常量并不同。

static NSString * const ...
你永遠(yuǎn)不能在 init (以及其他初始化函數(shù))里面用 getter 和 setter 方法,你應(yīng)該直接訪問實例變量。記住一個對象是僅僅在 init 返回的時候,才會被認(rèn)為是初始化完成到一個狀態(tài)了。

當(dāng)使用 setter/getter 方法的時候盡量使用點符號。

復(fù)制代碼 代碼如下:

// 推薦
view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication].delegate;

// 不推薦
[view setBackgroundColor:[UIColor orangeColor]];
UIApplication.sharedApplication.delegate;


使用點符號會讓表達(dá)更加清晰并且?guī)椭鷧^(qū)分屬性訪問和方法調(diào)用。

屬性定義

復(fù)制代碼 代碼如下:

@property (nonatomic, readwrite, copy) NSString *name;

屬性的參數(shù)應(yīng)該按照這個順序排列: 原子性,讀寫和內(nèi)存管理。

習(xí)慣上修改某個屬性的修飾符時,一般從屬性名從右向左搜索需要修動的修飾符。最可能從最右邊開始修改這些屬性的修飾符,根據(jù)經(jīng)驗這些修飾符被修改的可能性從高到底應(yīng)為:內(nèi)存管理 > 讀寫權(quán)限 >原子操作
你必須使用 nonatomic,除非特別需要的情況。在iOS中,atomic帶來的鎖特別影響性能。

如果想要一個公開的getter和私有的setter,你應(yīng)該聲明公開的屬性為 readonly 并且在類擴(kuò)展總重新定義通用的屬性為 readwrite 的。

復(fù)制代碼 代碼如下:

//.h文件中
@interface MyClass : NSObject
@property (nonatomic, readonly, strong) NSObject *object;
@end

復(fù)制代碼 代碼如下:

//.m文件中
@interface MyClass ()
@property (nonatomic, readwrite, strong) NSObject *object;
@end

復(fù)制代碼 代碼如下:

@implementation MyClass
//Do Something cool
@end

描述BOOL屬性的詞如果是形容詞,那么setter不應(yīng)該帶is前綴,但它對應(yīng)的 getter 訪問器應(yīng)該帶上這個前綴。

@property (assign, getter=isEditable) BOOL editable;
任何可以用來用一個可變的對象設(shè)置的((比如 NSString,NSArray,NSURLRequest))屬性的的內(nèi)存管理類型必須是 copy 的。(原文中是這樣說的,但是我理解的話并不是絕對的。如果不想讓原來的可變對象影響到類的這個相應(yīng)屬性,那么就需要用copy,這樣在賦值的時候可變對象會首先進(jìn)行copy完成深拷貝,再把拷貝出的值賦給類的屬性,這樣就能保證類屬性和原來的可變對象影響并不影響。但是如果想讓類屬性對原來的可變對象是一個強(qiáng)引用,指向這個可變對象,那么會用strong。)

你應(yīng)該同時避免暴露在公開的接口中可變的對象,因為這允許你的類的使用者改變類自己的內(nèi)部表示并且破壞類的封裝。你可以提供可以只讀的屬性來返回你對象的不可變的副本。

復(fù)制代碼 代碼如下:

/* .h */
@property (nonatomic, readonly) NSArray *elements

/* .m */
- (NSArray *)elements {
  return [self.mutableElements copy];
}


雖然使用懶加載在某些情況下很不錯,但是使用前應(yīng)當(dāng)深思熟慮,因為懶加載通常會產(chǎn)生一些副作用。(但是懶加載還是比較常用的,比如下面的例子)

副作用指當(dāng)調(diào)用函數(shù)時,除了返回函數(shù)值之外,還對主調(diào)用函數(shù)產(chǎn)生附加的影響。例如修改全局變量(函數(shù)外的變量)或修改參數(shù)。函數(shù)副作用會給程序設(shè)計帶來不必要的麻煩,給程序帶來十分難以查找的錯誤,并且降低程序的可讀性。

復(fù)制代碼 代碼如下:

- (NSDateFormatter *)dateFormatter {
  if (!_dateFormatter) {
    _dateFormatter = [[NSDateFormatter alloc] init];
        NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
        [_dateFormatter setLocale:enUSPOSIXLocale];
        [_dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS"];//毫秒是SSS,而非SSSSS
  }
  return _dateFormatter;
}

三、方法
1.參數(shù)斷言

你的方法可能要求一些參數(shù)來滿足特定的條件(比如不能為nil),在這種情況下啊最好使用 NSParameterAssert() 來斷言條件是否成立或是拋出一個異常。

復(fù)制代碼 代碼如下:

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self testMethodWithAParameter:0];
}

- (void)testMethodWithAParameter: (int)value
{
    NSParameterAssert(value != 0);

    NSLog(@"正確執(zhí)行");
}


在此例中, 如果傳的參數(shù)為0,那么程序會拋出異常。

2.私有方法

永遠(yuǎn)不要在你的私有方法前加上 _ 前綴。這個前綴是 Apple 保留的。不要冒重載蘋果的私有方法的險。

當(dāng)你要實現(xiàn)相等性的時候記住這個約定:你需要同時實現(xiàn)isEqual 和 hash方法。如果兩個對象是被isEqual認(rèn)為相等的,它們的 hash 方法需要返回一樣的值。但是如果 hash 返回一樣的值,并不能確保他們相等。

復(fù)制代碼 代碼如下:

@implementation ZOCPerson

- (BOOL)isEqual:(id)object {
    if (self == object) {
        return YES;
    }

    if (![object isKindOfClass:[ZOCPerson class]]) {
        return NO;
    }

    // check objects properties (name and birthday) for equality (檢查對象屬性(名字和生日)的相等性
    ...
    return propertiesMatch;
}

- (NSUInteger)hash {
    return [self.name hash] ^ [self.birthday hash];
}

@end


你總是應(yīng)該用 isEqualTo<#class-name-without-prefix#>: 這樣的格式實現(xiàn)一個相等性檢查方法。如果你這樣做,會優(yōu)先調(diào)用這個方法來避免上面的類型檢查。

所以一個完整的 isEqual 方法應(yīng)該是這樣的:

復(fù)制代碼 代碼如下:

- (BOOL)isEqual:(id)object {
    if (self == object) {
      return YES;
    }

    if (![object isKindOfClass:[ZOCPerson class]]) {
      return NO;
    }

    return [self isEqualToPerson:(ZOCPerson *)object];
}

- (BOOL)isEqualToPerson:(Person *)person {
    if (!person) {
        return NO;
    }

    BOOL namesMatch = (!self.name && !person.name) ||
                       [self.name isEqualToString:person.name];
    BOOL birthdaysMatch = (!self.birthday && !person.birthday) ||
                           [self.birthday isEqualToDate:person.birthday];

  return haveEqualNames && haveEqualBirthdays;
}


四、Category
category 方法前加上自己的小寫前綴以及下劃線。(真的很丑,但是蘋果也推薦這樣做)
復(fù)制代碼 代碼如下:

- (id)zoc_myCategoryMethod

這是非常必要的。因為如果在擴(kuò)展的 category 或者其他 category 里面已經(jīng)使用了同樣的方法名,會導(dǎo)致不可預(yù)計的后果。(會調(diào)用最后一個加載的方法)
復(fù)制代碼 代碼如下:

// 推薦
@interface NSDate (ZOCTimeExtensions)
- (NSString *)zoc_timeAgoShort;
@end

復(fù)制代碼 代碼如下:

// 不推薦
@interface NSDate (ZOCTimeExtensions)
- (NSString *)timeAgoShort;
@end

推薦使用Category來根據(jù)不同功能對方法進(jìn)行分組。
復(fù)制代碼 代碼如下:

@interface NSDate : NSObject <NSCopying, NSSecureCoding>

@property (readonly) NSTimeInterval timeIntervalSinceReferenceDate;

@end


復(fù)制代碼 代碼如下:

@interface NSDate (NSDateCreation)

+ (instancetype)date;
+ (instancetype)dateWithTimeIntervalSinceNow:(NSTimeInterval)secs;
+ (instancetype)dateWithTimeIntervalSinceReferenceDate:(NSTimeInterval)ti;
+ (instancetype)dateWithTimeIntervalSince1970:(NSTimeInterval)secs;
+ (instancetype)dateWithTimeInterval:(NSTimeInterval)secsToBeAdded sinceDate:(NSDate *)date;
// ...
@end


五、NSNotification
當(dāng)你定義你自己的 NSNotification 的時候你應(yīng)該把你的通知的名字定義為一個字符串常量,就像你暴露給其他類的其他字符串常量一樣。你應(yīng)該在公開的接口文件中將其聲明為 extern 的, 并且在對應(yīng)的實現(xiàn)文件里面定義。

因為你在頭文件中暴露了符號,所以你應(yīng)該按照統(tǒng)一的命名空間前綴法則,用類名前綴作為這個通知名字的前綴。(通常在頭文件中對外提供的常量都需要加上前綴,聲明extern + const,并且并不是在頭文件中定義,而是在實現(xiàn)文件中定義。如果不是對外公開的常量,那么通常直接在實現(xiàn)文件里聲明為static + const,并且也要加上前綴,直接在后面進(jìn)行定義。)

同時,用一個 Did/Will 這樣的動詞以及用 "Notifications" 后綴來命名這個通知也是一個好的實踐。

復(fù)制代碼 代碼如下:

// Foo.h
extern NSString * const ZOCFooDidBecomeBarNotification

// Foo.m
NSString * const ZOCFooDidBecomeBarNotification = @"ZOCFooDidBecomeBarNotification";


相關(guān)文章

  • 110.iOS10新特性適配教程XCode8新特性解析

    110.iOS10新特性適配教程XCode8新特性解析

    這篇文章主要介紹了110.iOS10新特性適配教程XCode8新特性解析的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • IOS游戲開發(fā)之五子棋OC版

    IOS游戲開發(fā)之五子棋OC版

    五子棋是大家比較熟悉的一款小游戲,相信很多人用多種語言寫過五子棋小游戲,本文試著用OC實現(xiàn)了一下,在這里給大家分享一下。有需要的可以參考學(xué)習(xí)。
    2016-08-08
  • iOS基礎(chǔ)知識之@property 和 Ivar 的區(qū)別

    iOS基礎(chǔ)知識之@property 和 Ivar 的區(qū)別

    這篇文章主要介紹了iOS基礎(chǔ)知識之@property 和 Ivar 的區(qū)別介紹,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-08-08
  • iOS TabBarItem設(shè)置紅點(未讀消息)

    iOS TabBarItem設(shè)置紅點(未讀消息)

    本文主要介紹了iOS利用TabBarItem設(shè)置紅點(未讀消息)的相關(guān)知識。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-04-04
  • iOS中一行代碼實現(xiàn) UIView 鏤空效果

    iOS中一行代碼實現(xiàn) UIView 鏤空效果

    這篇文章主要介紹了一行代碼實現(xiàn) UIView 鏤空效果,這是一種實現(xiàn) UIView 鏤空效果的方案,可以快速實現(xiàn)任意形狀的鏤空、文字的鏤空、帶鏤空的毛玻璃效果等。需要的朋友可以參考下
    2018-11-11
  • iOS實現(xiàn)PDF文件瀏覽功能

    iOS實現(xiàn)PDF文件瀏覽功能

    這篇文章主要為大家詳細(xì)介紹了iOS實現(xiàn)PDF文件瀏覽功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • 剖析iOS開發(fā)中Cocos2d-x的內(nèi)存管理相關(guān)操作

    剖析iOS開發(fā)中Cocos2d-x的內(nèi)存管理相關(guān)操作

    這篇文章主要介紹了剖析iOS開發(fā)中Cocos2d-x的內(nèi)存管理相關(guān)操作,Cocos2d-x是開發(fā)游戲的利器,需要的朋友可以參考下
    2015-10-10
  • iOS10實現(xiàn)推送功能時的注意點和問題總結(jié)

    iOS10實現(xiàn)推送功能時的注意點和問題總結(jié)

    很多朋友都反饋,發(fā)現(xiàn)了iOS9升級到iOS10推送功能不正常的問題,所以這篇文章總結(jié)了一下要點,親們可以根據(jù)以下步驟,逐步排查問題,也可以逐步實現(xiàn)iOS10的推送功能。下面來一起看看吧。
    2016-09-09
  • IOS 開發(fā)之 NSMutableArray與NSArray 的區(qū)別

    IOS 開發(fā)之 NSMutableArray與NSArray 的區(qū)別

    這篇文章主要介紹了IOS 開發(fā)之 NSMutableArray與NSArray 的區(qū)別的相關(guān)資料,希望通過本文能掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-09-09
  • iOS圖片界面翻頁切換效果

    iOS圖片界面翻頁切換效果

    這篇文章主要為大家詳細(xì)介紹了iOS圖片界面翻頁切換效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11

最新評論

达孜县| 屏南县| 微山县| 高阳县| 丘北县| 宁海县| 漯河市| 遵化市| 海阳市| 社旗县| 噶尔县| 吉隆县| 建平县| 武城县| 从江县| 广宁县| 乐山市| 清河县| 绥滨县| 密云县| 咸阳市| 综艺| 东丰县| 玉林市| 库尔勒市| 龙胜| 宁河县| 沈阳市| 苏尼特右旗| 绥中县| 大港区| 汝州市| 宜章县| 通许县| 云林县| 嘉峪关市| 阳高县| 邯郸县| 南乐县| 平利县| 鱼台县|