I am writing a struct in Swift:
struct LevelDictionary {
let kNumberOfSegments: Int = 10
static func loadLevelData() -> NSDictionary {
for var segmentNumber = 0; segmentNumber < kNumberOfSegments; ++segmentNumber {
//My code here
}
return dictionary
}
}
For some reason I get an error on compiling: Instance member 'kNumberOfSegments' cannot be used on type 'LevelDictionary'. What am I missing? I get the same error when I set up LevelDictionary as a Class.
loadLevelData() is a static function which is called on "class" level
LevelDictionary.loadLevelData()
To use kNumberOfSegments in the static function it must be static as well
static let kNumberOfSegments: Int = 10
The direct answer to your question is that you can't use a property in class scope.
A different answer is that you seem to want a static function that returns a dictionary after doing something a certain number of times; which is why you have kNumberOfSegments in the first place. But do you really need to have a variable for something that you aren't going to use again. Another way to do this is to have a default variable in your class method:
struct LevelDictionary {
static func loadLevelData(numberOfSegments: Int = 10) -> NSDictionary {
for segment in 0 ..< numberOfSegments {
// your code here
}
return dictionary
}
}
Now you can call the method without an argument to use the default
let dictionary = LevelDictionary.loadLevelData() // Will use 10 segments
Or you can use a parameter to override the default
let dictianary = LevelDictionary.loadLevelData(20) // Will use 20 segments
You can't use instance member variables/constants inside the static function. (In terms of Objective C you can't use instance member objects inside class function)
Either you should declare the kNumberOfSegments as static or make that function as non-static. I prefer the first option,
struct LevelDictionary
{
static let kNumberOfSegments: Int = 10
static func loadLevelData() -> NSDictionary
{
for var segmentNumber = 0; segmentNumber < kNumberOfSegments; ++segmentNumber
{
//My code here
}
return dictionary
}
}
Related
Suppose I want to convert a UNIX integer into DateTime Format when called upon.
(That's just an example)
I want to create a function just like .toUpperCase(); , .toString(); where function takes that particular item as argument without writing inside brackets. I did try going inside these default core functions but didn't help.
How do I do that for custom functions?
right now I'm here:
//------------- main()----------//
void main() {
int unixDT = 1619691181;
// print(unixDT.toDateString()); //<-----this is what I'm looking for
}
//------- This is a function that should be in another-separate dart file-------//
String toDateString(int dt) {
DateTime datetime = new DateTime.fromMillisecondsSinceEpoch(dt);
return datetime.toString();
}
If you need clarification, please comment down. This is my very first question on StackOverflow so I apologize for mistakes if any.
Sounds like you are looking for extension methods:
void main() {
const unixDT = 1619691181;
print(unixDT.toDateString()); // 1970-01-19 18:54:51.181
}
extension IntToDateStringExtension on int {
String toDateString() => DateTime.fromMillisecondsSinceEpoch(this).toString();
}
You can use extension methods for this situations. You can add a method in Integer. For more details https://dart.dev/guides/language/extension-methods
You can try to use this to refer to same object that is calling that method, Hope that will help
You should use extension methods
Example:
extension ExtendedDynamic on dynamic {
double toDouble() {
final sValue = this?.toString() ?? '';
final double parsedValue = double?.tryParse(sValue) ?? 0.0;
return parsedValue;
}
}
void someMethod() {
final dynamic test = 0.0;
print(test.toDouble());
}
In your case it will be like this:
extension ExtendedInt on int {
String toDateString() {
final dateString = 'your code...';
return dateString;
}
}
void someMethod() {
int unixDT = 1619691181;
print(unixDT.toDateString());
}
Important thing : Wherever you want to use this extension, you must import it
import 'package:yourProject/extensions/int_extention.dart';
I am trying to override a method provided by an interface/API and have to assign a new value to one of the method's argument. If I try to assign to the passed argument, it'll give an error.
override _.Emit(eventInfo:SequenceStartEventInfo, emitter:IEmitter) =
eventInfo <- SequenceStartEventInfo(eventInfo.Source)
[...]
I am looking for behavior matching the following C# code:
public override void Emit(SequenceStartEventInfo eventInfo, IEmitter emitter) {
eventInfo = new SequenceStartEventInfo(eventInfo.Source)
...
}
If I change it and try to pass by reference (eventInfo:byref<SequenceStartEventInfo>) then it'll no longer match the available overloads.
The F# language reference on parameters and methods doesn't provide any help when dealing with this specific case. What is the best way to handle this Scenario?
In C# you can assign a new value to the argument variable, but as it is not passed by reference, this won't change the variable of the caller (even though the passed object is a reference type):
public static void Main()
{
var rt = new RefType { Value = 3 };
Change(rt);
Console.WriteLine(rt.Value); // still 3
}
public class RefType {
public int Value { get; set; }
}
public static void Change(RefType notByRef){
notByRef = new RefType { Value = 42 };
}
the F# equivalent (where parameters are immutable) would be shadowing:
type RefType() =
member val Value = 0 with get, set
let Change notByRef =
let notByRef = RefType(Value = 42);
// now, `notByRef` hides the method parameter
()
let [<EntryPoint>] Main _ =
let rt = RefType(Value = 3);
Change(rt);
printfn "%i" rt.Value // still 3
0
I have a custom collection class with an embedded array written in Obj-c. The class implements NSFastEnumerator protocol in order to be iterable in Obj-c.
For my Swift classes I had to add the following code based on apporaches on SOF.
extension CustomCollection: SequenceType {
public func generate() -> NSFastGenerator {
return NSFastGenerator(self)
}
}
Which again makes it iterable in Swift classes.
All is good until I need to use this class as a Generic type in one of my Swift base classes.
class SomeBaseClass<T: CustomCollection> {
typealias Collection = T
var model: Collection?
// Implementation goes here
}
When I try to iterate over my 'model' property, I get Command Signal Failure Error during build.
Any idea how this needs to be done and whether it's even possible to be done?
Running XCode 7 beta 6 and Swift 2.0
Thanks.
Here is what I came up with Xcode 7.0.1:
First the CustomCollection class. I've keep it simple since I don't know what yours is doing.
public class CustomCollection: NSFastEnumeration
{
var array: NSMutableArray = []
#objc public func countByEnumeratingWithState(state: UnsafeMutablePointer<NSFastEnumerationState>, objects buffer: AutoreleasingUnsafeMutablePointer<AnyObject?>, count len: Int) -> Int {
var index = 0
if state.memory.state != 0 {
index = Int(state.memory.state)
}
if index >= self.array.count {
return 0
}
var array = Array<AnyObject?>()
while (index < self.array.count && array.count < len)
{
array.append(self.array[index++])
}
let cArray: UnsafeMutablePointer<AnyObject?> = UnsafeMutablePointer<AnyObject?>.alloc(array.count)
cArray.initializeFrom(array)
state.memory.state = UInt(index)
state.memory.itemsPtr = AutoreleasingUnsafeMutablePointer<AnyObject?>.init(cArray)
return array.count
}
}
Then there's the code you provided.
extension CustomCollection: SequenceType {
public func generate() -> NSFastGenerator {
return NSFastGenerator(self)
}
}
class SomeBaseClass<T: CustomCollection>
{
typealias Collection = T
var model: Collection?
}
With all this, I'm able to run the following
var myModel = CustomCollection()
myModel.array.addObject("This")
myModel.array.addObject("is")
myModel.array.addObject("a")
myModel.array.addObject(["complex", "test"])
var myVar = SomeBaseClass()
myVar.model = myModel
for myObject in myVar.model!
{
print(myObject)
}
And the console prints
This
is
a
(
complex,
test
)
Hope it helps!
I am writing a swift application that requires handling private keys in memory. Because of the sensitivity of such objects, the keys need to be cleared (a.k.a. written to all zeros) when the object is deallocated, and the memory cannot be paged to disk (which is typically done using mlock()).
In Objective-C, you can provide a custom CFAllocator object, which allows you to use your own functions to allocate/deallocate/reallocate the memory used by an object.
So one solution is to just implement a "SecureData" object in objective-c, which internally creates an NSMutableData object using a custom CFAllocator (also in objective-c).
However, is there any way for me to provide my own custom memory allocation functions for a pure swift object (for example, a struct or a [UInt8])? Or is there a better, "proper" way to implement secure memory like this in swift?
If you want complete control over a region of memory you allocate yourself, you can use UnsafePointer and co:
// allocate enough memory for ten Ints
var ump = UnsafeMutablePointer<Int>.alloc(10)
// memory is in an uninitialized raw state
// initialize that memory with Int objects
// (here, from a collection)
ump.initializeFrom(reverse(0..<10))
// memory property gives you access to the underlying value
ump.memory // 9
// UnsafeMutablePointer acts like an IndexType
ump.successor().memory // 8
// and it has a subscript, but it's not a CollectionType
ump[3] // = 6
// wrap it in an UnsafeMutableBufferPointer to treat it
// like a collection (or UnsafeBufferPointer if you don't
// need to be able to alter the values)
let col = UnsafeMutableBufferPointer(start: ump, count: 10)
col[3] = 99
println(",".join(map(col,toString)))
// prints 9,8,7,99,5,4,3,2,1,0
ump.destroy(10)
// now the allocated memory is back in a raw state
// you could re-allocate it...
ump.initializeFrom(0..<10)
ump.destroy(10)
// when you're done, deallocate the memory
ump.dealloc(10)
You can also have UnsafePointer point to other memory, such as memory you’re handed by some C API.
UnsafePointer can be passed into C functions that take a pointer to a contiguous block of memory. So for your purposes, you could then pass this pointer into a function like mlock:
let count = 10
let ump = UnsafeMutablePointer.allocate<Int>(count)
mlock(ump, UInt(sizeof(Int) * count))
// initialize, use, and destroy the memory
munlock(ump, UInt(sizeof(Int) * count))
ump.dealloc(count)
You can even hold your own custom types:
struct MyStruct {
let a: Int
let b: Int
}
var pointerToStruct = UnsafeMutablePointer<MyStruct>.alloc(1)
pointerToStruct.initialize(MyStruct(a: 1, b: 2))
pointerToStruct.memory.b // 2
pointerToStruct.destroy()
pointerToStruct.dealloc(1)
However be aware if doing this with classes, or even arrays or strings (or a struct that contains them), that all you will be holding in your memory is pointers to other memory that these objects allocate and own. If this matters to you (i.e. you are doing something special to this memory such as securing it, in your example), this is probably not what you want.
So either you need to use fixed-size objects, or make further use of UnsafePointer to hold pointers to more memory regions. If they don't need to dynamically resize, then just a single allocation of an unsafe pointer, possibly wrapped in a UnsafeBufferPointer for a collection interface, could do it.
If you need more dynamic behavior, below is a very bare-bones implementation of a collection that can resize as necessary, that could be enhanced to cover specialty memory-handling logic:
// Note this is a class not a struct, so it does NOT have value semantics,
// changing a copy changes all copies.
public class UnsafeCollection<T> {
private var _len: Int = 0
private var _buflen: Int = 0
private var _buf: UnsafeMutablePointer<T> = nil
public func removeAll(keepCapacity: Bool = false) {
_buf.destroy(_len)
_len = 0
if !keepCapacity {
_buf.dealloc(_buflen)
_buflen = 0
_buf = nil
}
}
public required init() { }
deinit { self.removeAll(keepCapacity: false) }
public var count: Int { return _len }
public var isEmpty: Bool { return _len == 0 }
}
To cover the requirements of MutableCollectionType (i.e. CollectionType plus assignable subscript):
extension UnsafeCollection: MutableCollectionType {
typealias Index = Int
public var startIndex: Int { return 0 }
public var endIndex: Int { return _len }
public subscript(idx: Int) -> T {
get {
precondition(idx < _len)
return _buf[idx]
}
set(newElement) {
precondition(idx < _len)
let ptr = _buf.advancedBy(idx)
ptr.destroy()
ptr.initialize(newElement)
}
}
typealias Generator = IndexingGenerator<UnsafeCollection>
public func generate() -> Generator {
return Generator(self)
}
}
And ExtensibleCollectionType, to allow for dynamic growth:
extension UnsafeCollection: ExtensibleCollectionType {
public func reserveCapacity(n: Index.Distance) {
if n > _buflen {
let newBuf = UnsafeMutablePointer<T>.alloc(n)
newBuf.moveInitializeBackwardFrom(_buf, count: _len)
_buf.dealloc(_buflen)
_buf = newBuf
_buflen = n
}
}
public func append(x: T) {
if _len == _buflen {
reserveCapacity(Int(Double(_len) * 1.6) + 1)
}
_buf.advancedBy(_len++).initialize(x)
}
public func extend<S: SequenceType where S.Generator.Element == T>
(newElements: S) {
var g = newElements.generate()
while let x: T = g.next() {
self.append(x)
}
}
}
I know this question is old but something for those who land here: since iOS 10 you can use Secure Enclave to store private keys securely. The way it works is that all the operations that require decryption is performed inside the Secure Enclave so you do not have to worry about runtime hooking of your classes or memory leaks.
Take a look here: https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/storing_keys_in_the_secure_enclave
Problem:
Is it possible to cast dynamically to a type?
For example, could this be possible, using mirrors:
var reflectee = im.getField(simpleName).reflectee;
var converted = testVal as reflectee.runtimeType;
Context:
I want to make a Mixin class which defines a validate method:
abstract class Validatable {
bool validate(Map document) {
}
}
It will iterate over the variables defined for the class where it is mixed in, and checks if the variable in the document are of the same type.
Now, it is working with getting the runtimeType of the respective variables, but it is very restrictive as it does not cast. For example:
var a = 1.1;
var b = 1;
print(a.runtimeType == b.runtimeType); // false
It would be better to better to check with as, but I cant see how to get this to work. Becase:
a = b;
print(a.runtimeType); // int
and not double, as one might expect.
Is it possible?
You could use
import 'dart:mirrors';
class A {
}
class B extends A {
}
class C extends A {
}
void main(args) {
var a = 1.1;
var b = 1;
var x = reflect(b);
print(x.type.isSubtypeOf(reflectType(num)));
print(x.type.isAssignableTo(reflectType(num)));
print(x.type.isAssignableTo(reflectType(double)));
var myb = new B();
print(reflect(myb).type.isSubtypeOf(reflectType(A)));
print(reflect(myb).type.isAssignableTo(reflectType(A)));
print(reflect(myb).type.isAssignableTo(reflectType(C)));
}