1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Support for using the Singleton<T> pattern with Objective-C objects.  A
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// SingletonObjC is the same as a Singleton, except the default traits are
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// appropriate for Objective-C objects.  A typical Objective-C object of type
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// NSExampleType can be maintained as a singleton and accessed with:
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   NSExampleType* exampleSingleton = SingletonObjC<NSExampleType>::get();
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The first time this is used, it will create exampleSingleton as the result
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// of [[NSExampleType alloc] init].  Subsequent calls will return the same
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// NSExampleType* object.  The object will be released by calling
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// -[NSExampleType release] when Singleton's atexit routines run
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// (see singleton.h).
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// For Objective-C objects initialized through means other than the
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// no-parameter -init selector, DefaultSingletonObjCTraits may be extended
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// as needed:
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   struct FooSingletonTraits : public DefaultSingletonObjCTraits<Foo> {
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//     static Foo* New() {
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//       return [[Foo alloc] initWithName:@"selecty"];
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//     }
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//   };
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   ...
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   Foo* widgetSingleton = SingletonObjC<Foo, FooSingletonTraits>::get();
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifndef BASE_MEMORY_SINGLETON_OBJC_H_
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define BASE_MEMORY_SINGLETON_OBJC_H_
323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#import <Foundation/Foundation.h>
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/singleton.h"
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Singleton traits usable to manage traditional Objective-C objects, which
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// are instantiated by sending |alloc| and |init| messages, and are deallocated
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// in a memory-managed environment when their retain counts drop to 0 by
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// sending |release| messages.
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<typename Type>
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct DefaultSingletonObjCTraits : public DefaultSingletonTraits<Type> {
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static Type* New() {
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return [[Type alloc] init];
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static void Delete(Type* object) {
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    [object release];
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Exactly like Singleton, but without the DefaultSingletonObjCTraits as the
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// default trait class.  This makes it straightforward for Objective-C++ code
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// to hold Objective-C objects as singletons.
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<typename Type,
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         typename Traits = DefaultSingletonObjCTraits<Type>,
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         typename DifferentiatingType = Type>
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass SingletonObjC : public Singleton<Type, Traits, DifferentiatingType> {
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif  // BASE_MEMORY_SINGLETON_OBJC_H_
62