count number of instances of a class swift
Inside initializer method you have to add one to your static var with
Car.carPopulation += 1
And you must implement de deinitializer to delete the car entity that is going to disappear
deinit
{
Car.carPopulation -= 1
}
Get number of instances of custom class
No you can not get directly. Whenever you create in instance add it any Array and then access it using that array properties.
Ex :
NSMutableArray *allInstancesArray = [NSMutableArray new];
PaperPack *pack1 = [[PaperPack alloc] init];
pack1.title = @"Title 1";
pack1.author = @"Author";
[allInstancesArray addObject:pack1];
PaperPack *pack2 = [[PaperPack alloc] init];
pack1.title = @"Title 2";
pack1.author = @"Author";
[allInstancesArray addObject:pack2];
Then get count as :
NSLog(@"TOTAL INSTANCES : %d",[allInstancesArray count]);
How to count how many times all classes are called
If you mean visited each view controller, when you say visited each class. Then i'd recommend you do it viewDidAppear
.
class YourViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let key = String(describing: type(of: self))
let count = UserDefaults.standard.value(forKey: key) as? Int ?? 0
UserDefaults.standard.set(value + 1, forKey: key)
}
}
To make it simpler, you could use an extension on UIViewController
.
extension UIViewController {
func updateVisitCount() {
let key = String(describing: type(of: self))
let count = UserDefaults.standard.value(forKey: key) as? Int ?? 0
UserDefaults.standard.set(count + 1, forKey: key)
}
}
Or, if you need this for every view controller that you create, then you can create a base view controller which you would use everywhere instead of UIViewController
.
class BaseViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
updateVisitCount()
}
}
Count number of objects of class
The obvious solution is to use an array, put all your recipes in an array and return the count of such array on the tableView datasource. Something like
// Declare it on your interface
@property (nonatomic, strong) NSArray *recipes;
...
// On your viewDidLoad
self.recipes = @[recipe1, recipe2]; // and so on
...
// UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.recipes.count;
}
How to count occurrences of an element in a Swift array?
Swift 3 and Swift 2:
You can use a dictionary of type [String: Int]
to build up counts for each of the items in your [String]
:
let arr = ["FOO", "FOO", "BAR", "FOOBAR"]
var counts: [String: Int] = [:]
for item in arr {
counts[item] = (counts[item] ?? 0) + 1
}
print(counts) // "[BAR: 1, FOOBAR: 1, FOO: 2]"
for (key, value) in counts {
print("\(key) occurs \(value) time(s)")
}
output:
BAR occurs 1 time(s)
FOOBAR occurs 1 time(s)
FOO occurs 2 time(s)
Swift 4:
Swift 4 introduces (SE-0165) the ability to include a default value with a dictionary lookup, and the resulting value can be mutated with operations such as +=
and -=
, so:
counts[item] = (counts[item] ?? 0) + 1
becomes:
counts[item, default: 0] += 1
That makes it easy to do the counting operation in one concise line using forEach
:
let arr = ["FOO", "FOO", "BAR", "FOOBAR"]
var counts: [String: Int] = [:]
arr.forEach { counts[$0, default: 0] += 1 }
print(counts) // "["FOOBAR": 1, "FOO": 2, "BAR": 1]"
Swift 4: reduce(into:_:)
Swift 4 introduces a new version of reduce
that uses an inout
variable to accumulate the results. Using that, the creation of the counts truly becomes a single line:
let arr = ["FOO", "FOO", "BAR", "FOOBAR"]
let counts = arr.reduce(into: [:]) { counts, word in counts[word, default: 0] += 1 }
print(counts) // ["BAR": 1, "FOOBAR": 1, "FOO": 2]
Or using the default parameters:
let counts = arr.reduce(into: [:]) { $0[$1, default: 0] += 1 }
Finally you can make this an extension of Sequence
so that it can be called on any Sequence
containing Hashable
items including Array
, ArraySlice
, String
, and String.SubSequence
:
extension Sequence where Element: Hashable {
var histogram: [Element: Int] {
return self.reduce(into: [:]) { counts, elem in counts[elem, default: 0] += 1 }
}
}
This idea was borrowed from this question although I changed it to a computed property. Thanks to @LeoDabus for the suggestion of extending Sequence
instead of Array
to pick up additional types.
Examples:
print("abacab".histogram)
["a": 3, "b": 2, "c": 1]
print("Hello World!".suffix(6).histogram)
["l": 1, "!": 1, "d": 1, "o": 1, "W": 1, "r": 1]
print([1,2,3,2,1].histogram)
[2: 2, 3: 1, 1: 2]
print([1,2,3,2,1,2,1,3,4,5].prefix(8).histogram)
[1: 3, 2: 3, 3: 2]
print(stride(from: 1, through: 10, by: 2).histogram)
[1: 1, 3: 1, 5: 1, 7: 1, 9: 1]
Get instance count of a specific class in Objective-C/IOS
Per request, I've mocked up a category that will keep count of allocated objects using method swizzling and a singleton. This was a quick mock up, so there are a few issues with it (one being that initializing anything that is contained within the storage class will cause an infinite loop). Mind you, this is for keeping track of many objects and should not be used in a production environment. The best methodology overall is to use the instruments tool.
#import "NSObject+Initializer.h"
#import <objc/runtime.h>
@interface ObjectCounter : NSObject
+ (instancetype)sharedObjectCounter;
@property (strong, nonatomic) NSMutableDictionary *objectCounterDictionary;
@end
@implementation ObjectCounter
+ (instancetype)sharedObjectCounter
{
static ObjectCounter *objectCounter;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
objectCounter = [ObjectCounter new];
objectCounter.objectCounterDictionary = [NSMutableDictionary new];
});
return objectCounter;
}
@end
@implementation NSObject (Initializer)
+ (NSNumber *)initializedCount
{
NSLog(@"Dict: %@", [ObjectCounter sharedObjectCounter].objectCounterDictionary);
return [ObjectCounter sharedObjectCounter].objectCounterDictionary[NSStringFromClass([self class])];
}
+ (id)alloc_swizzled
{
NSLog(@"Swizzled");
NSString *className = NSStringFromClass([self class]);
if (![className isEqualToString:NSStringFromClass([NSMutableDictionary class])] && ![className isEqualToString:NSStringFromClass([ObjectCounter class])]) {
ObjectCounter *counter = [ObjectCounter sharedObjectCounter];
NSMutableDictionary *objectDictionary = counter.objectCounterDictionary;
NSNumber *count = objectDictionary[className];
count = count ? @(count.integerValue + 1) : @0;
objectDictionary[className] = count;
}
return [self alloc_swizzled];
}
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(alloc);
SEL swizzledSelector = @selector(alloc_swizzled);
Method originalMethod = class_getClassMethod(class, originalSelector);
Method swizzledMethod = class_getClassMethod(class, swizzledSelector);
BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
Related Topics
Location Access Request in iOS 11
How to Get The Count of a Type Conforming to 'sequence'
Swift System Version Checking on Ubuntu
Control a Nstabviewcontroller from Parent View
Scenkit Eulerangles Strange Values During Rotation
Test Enum for Equality in for ... Where Clause
Multiline Editable Text Field in Swiftui
Key Data Not Storing to Icloud with Nsubiquitouskeyvaluestore.Defaultstore
Access Parent Project Other_Swift_Flags from Pod
Is There a Method to Check The UIcollectionview Item Drag Cancellation If The Item Wasn't Moved
Can't Load Images on MAC Screensaver Release Build (It Works on Xcode Debug Build)
How to Cast from Cftyperef to Axuielement in Swift
Does Swift Allow Code Blocks Without Conditions/Loops to Reduce Local Variable Scope
Facebook Graphrequest for Swift 5 and Facebook Sdk 5
Save/Copy a File from Bundle to Desktop Using Nssavepanel
Converting Scanlocation from Utf16 Units to Character Index in Nsscanner (Swift)