2012-03-05 19 views
21

Tôi có một số mã mà tôi muốn chạy chỉ một lần trong MainViewController của mình. Nó sẽ chạy mỗi khi người dùng khởi động ứng dụng, nhưng chỉ sau khi MainViewController đã tải.Làm cho một số mã chỉ chạy sau khi

Tôi không muốn chạy nó trong -(void)applicationDidFinishLaunching:(UIApplication *)application.

Đây là ý tưởng tôi đã:

MainViewController.h

@interface IpadMainViewController : UIViewController <UISplitViewControllerDelegate> { 
    BOOL hasRun; 
} 

@property (nonatomic, assign) BOOL hasRun; 

MainViewController.m

@synthesize hasRun; 

-(void)viewDidLoad { 
    [super viewDidLoad]; 
    if (hasRun == 0) { 
     // Do some stuff 
     hasRun = 1; 
    } 
} 

Bất kỳ ý tưởng?

+0

Các bạn đã thử mã của bạn? – Jim

+0

Có gì sai khi chạy ứng dụng '- (void)DidFinishLaunching: (UIApplication *) application' hoặc mã của bạn? Hoặc nếu bạn không phân bổ MainViewCOntroller của bạn, nó sẽ được chạy một lần anyways – Seega

+1

Một lần cho mỗi _activation_ (tức là, một khi lúc khởi động và một lần nữa khi nó trở về từ nền), hoặc một lần mỗi lần nó được nạp vào bộ nhớ? –

Trả lời

72

Bạn có thể sử dụng dispatch_once:

Objective-C

static dispatch_once_t once; 
dispatch_once(&once,^{ 
    NSLog(@"Do it once"); 
}); 

Swift

static var token: dispatch_once_t = 0 

dispatch_once(&token) { 
    NSLog("Do it once") 
} 
+2

+1; GCD là một lựa chọn sạch hơn cho nhiệm vụ này hơn là duy trì trạng thái BOOL trong lớp học của bạn –

+23

Lưu ý rằng đây là một lần cho mỗi ứng dụng được tải vào bộ nhớ. Mã sẽ không được chạy một lần nữa cho một thể hiện của lớp này đang được tạo ra (bit này tôi gần đây), và cũng sẽ không được chạy một lần nữa khi ứng dụng trở về nền trước từ hệ thống treo. –

+0

Câu trả lời hay. Điều này cảm thấy thanh lịch hơn nhiều so với ý tưởng ban đầu của tôi. Tôi đã học được điều gì đó. Cảm ơn! –

7

Tôi không thấy bất kỳ sự cố nào với mã đó. Tôi thích sử dụng một BOOL (như bạn đã làm) và sau đó gán hoặc YES/NO hoặc TRUE/FALSE chỉ để mã đọc độc đáo hơn. Tôi sẽ gán TRUE cho firstRun trong didFinishLaunching, và thiết lập nó FALSE sau khi mã thực hiện. Trong mã của tôi những loại điều kiện thường trông như thế này:

@synthesize firstRun; 

-(void)viewDidLoad { 
    [super viewDidLoad]; 
    if (firstRun) { 
     // code to run only once goes here 
     firstRun = FALSE; 
    } 
} 
+0

Câu trả lời khác đề xuất Grand Central Dispatch được cho là một cách tiếp cận tốt hơn. Mặt khác, như một công nghệ cấp BSD nó có một đường cong học tập dốc hợp lý xem xét rằng đây là một câu hỏi "cơ bản". Nếu bạn muốn làm những gì bạn đã hỏi, mã này hơi sạch hơn bản gốc của bạn - nếu bạn muốn thử một cách tiếp cận nâng cao hơn để quản lý tác vụ GCD là rất mạnh mẽ. – Dylan

-2

Với Swift2.0 , Xcode 7.0

var token: dispatch_once_t = 0 

override func viewDidLoad() { 
    super. viewDidLoad() 
    dispatch_once(&token) { 
     println("This is printed only on the first call to test()") 
    } 
    println("This is printed for each call to test()") 
} 
-2

cho Swift2.2, Xcode 7.3:

static var token: dispatch_once_t = 0 

dispatch_once(&YourClassName.token) { 
    NSLog("Do it once") 
} 

Coi chừng "YourClassName.token"

Các vấn đề liên quan